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) { 3043232da50SPeter Brune 305aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 306aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 307aa3661deSLisandro Dalcin ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 308aa3661deSLisandro Dalcin } else { 309aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 3103232da50SPeter Brune provided preconditioner Jacobian with the default matrix free version. */ 3113232da50SPeter Brune 3123232da50SPeter Brune ierr = SNESSetJacobian(snes,J,J,0,0);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; 3784e269d77SPeter Brune void *ctxsave; 3794e269d77SPeter 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; 3884e269d77SPeter Brune ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,&jac,&ctxsave);CHKERRQ(ierr); 3894e269d77SPeter Brune /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */ 3904e269d77SPeter Brune if (jac == SNESDefaultComputeJacobianColor) { 3914e269d77SPeter Brune ierr = SNESSetJacobian(snes,PETSC_NULL,PETSC_NULL,SNESDefaultComputeJacobianColor,0);CHKERRQ(ierr); 392dfe15315SJed Brown } 3934e269d77SPeter Brune } 3944e269d77SPeter Brune /* put the previous context back */ 3954e269d77SPeter Brune 396dfe15315SJed Brown ierr = SNESComputeJacobian(snes,X,&A,&B,mstruct);CHKERRQ(ierr); 3974e269d77SPeter Brune if (snes->dm != dmsave && jac == SNESDefaultComputeJacobianColor) { 3984e269d77SPeter Brune ierr = SNESSetJacobian(snes,PETSC_NULL,PETSC_NULL,jac,ctxsave);CHKERRQ(ierr); 3994e269d77SPeter Brune } 4004e269d77SPeter 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) { 433a33a0d9fSJed Brown SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_PLIB,"SNESDM not properly configured"); 4343232da50SPeter Brune } else if (!snes->jacobian && snes->mf) { 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); 4413232da50SPeter Brune ierr = SNESSetJacobian(snes,J,J,0,0);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 5014619e776SBarry Smith . -snes_monitor_lg_residualnorm - plots residual norm at each iteration 502*459f5d12SBarry Smith . -snes_monitor_lg_range - plots residual norm at each iteration 503e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 504e2e60de9SPeter Brune . -snes_fd_color - use finite differences with coloring to compute Jacobian 5055968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 506fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 50782738288SBarry Smith 50882738288SBarry Smith Options Database for Eisenstat-Walker method: 509fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 5104b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 51136851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 51236851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 51336851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 51436851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 51536851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 51636851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 51782738288SBarry Smith 51811ca99fdSLois Curfman McInnes Notes: 51911ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 5200598bfebSBarry Smith the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>. 52183e2fdc7SBarry Smith 52236851e7fSLois Curfman McInnes Level: beginner 52336851e7fSLois Curfman McInnes 5249b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 5259b94acceSBarry Smith 52669ed319cSSatish Balay .seealso: SNESSetOptionsPrefix() 5279b94acceSBarry Smith @*/ 5287087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 5299b94acceSBarry Smith { 530d8f46077SPeter Brune PetscBool flg,pcset; 531d8f46077SPeter Brune PetscInt i,indx,lag,grids; 532aa3661deSLisandro Dalcin MatStructure matflag; 53385385478SLisandro Dalcin const char *deft = SNESLS; 53485385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 53585385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 536e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 537649052a6SBarry Smith PetscViewer monviewer; 53885385478SLisandro Dalcin PetscErrorCode ierr; 539c40d0f55SPeter Brune PCSide pcside; 540a64e098fSPeter Brune const char *optionsprefix; 5419b94acceSBarry Smith 5423a40ed3dSBarry Smith PetscFunctionBegin; 5430700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 544ca161407SBarry Smith 545186905e3SBarry Smith if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 5463194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 5477adad957SLisandro Dalcin if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; } 548b0a32e0cSBarry Smith ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 549d64ed03dSBarry Smith if (flg) { 550186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 5517adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 552186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 553d64ed03dSBarry Smith } 55490d69ab7SBarry Smith /* not used here, but called so will go into help messaage */ 555909c8a9fSBarry Smith ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 55693c39befSBarry Smith 557c60f73f4SPeter Brune ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr); 55857034d6fSHong Zhang ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 559186905e3SBarry Smith 56057034d6fSHong Zhang ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 561b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 562b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 56324254dc1SJed Brown ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 564ddf469c8SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr); 565acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr); 56685385478SLisandro Dalcin 567a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 568a8054027SBarry Smith if (flg) { 569a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 570a8054027SBarry Smith } 571e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 572e35cf81dSBarry Smith if (flg) { 573e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 574e35cf81dSBarry Smith } 575efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 576efd51863SBarry Smith if (flg) { 577efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 578efd51863SBarry Smith } 579a8054027SBarry Smith 58085385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 58185385478SLisandro Dalcin if (flg) { 58285385478SLisandro Dalcin switch (indx) { 5837f7931b9SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 5847f7931b9SBarry Smith case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 58585385478SLisandro Dalcin } 58685385478SLisandro Dalcin } 58785385478SLisandro Dalcin 588acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr); 589186905e3SBarry Smith 590fdacfa88SPeter Brune ierr = PetscOptionsEList("-snes_norm_type","SNES Norm type","SNESSetNormType",SNESNormTypes,5,"function",&indx,&flg);CHKERRQ(ierr); 591fdacfa88SPeter Brune if (flg) { ierr = SNESSetNormType(snes,(SNESNormType)indx);CHKERRQ(ierr); } 592fdacfa88SPeter Brune 59385385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 59485385478SLisandro Dalcin 595acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 596186905e3SBarry Smith 597fa9f3622SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 598fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 599fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 600fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 601fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 602fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 603fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 604186905e3SBarry Smith 60590d69ab7SBarry Smith flg = PETSC_FALSE; 606acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 607a6570f20SBarry Smith if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 608eabae89aSBarry Smith 609a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 610e8105e01SRichard Katz if (flg) { 611649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 612649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 613e8105e01SRichard Katz } 614eabae89aSBarry Smith 615b271bb04SBarry Smith ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 616b271bb04SBarry Smith if (flg) { 617b271bb04SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 618b271bb04SBarry Smith } 619b271bb04SBarry Smith 620a6570f20SBarry Smith ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 621eabae89aSBarry Smith if (flg) { 622649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 623f1bef1bcSMatthew Knepley ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 624e8105e01SRichard Katz } 625eabae89aSBarry Smith 626a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 627eabae89aSBarry Smith if (flg) { 628649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 629649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 630eabae89aSBarry Smith } 631eabae89aSBarry Smith 6325180491cSLisandro Dalcin ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 6335180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 6345180491cSLisandro Dalcin 63590d69ab7SBarry Smith flg = PETSC_FALSE; 636acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 637a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 63890d69ab7SBarry Smith flg = PETSC_FALSE; 639acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 640a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 64190d69ab7SBarry Smith flg = PETSC_FALSE; 642acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 643a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 64490d69ab7SBarry Smith flg = PETSC_FALSE; 6454619e776SBarry Smith ierr = PetscOptionsBool("-snes_monitor_lg_residualnorm","Plot function norm at each iteration","SNESMonitorLGResidualNorm",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 646*459f5d12SBarry Smith if (flg) { 647*459f5d12SBarry Smith PetscDrawLG ctx; 648*459f5d12SBarry Smith 649*459f5d12SBarry Smith ierr = SNESMonitorLGCreate(0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&ctx);CHKERRQ(ierr); 650*459f5d12SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))SNESMonitorLGDestroy);CHKERRQ(ierr); 651*459f5d12SBarry Smith } 65290d69ab7SBarry Smith flg = PETSC_FALSE; 6534619e776SBarry Smith ierr = PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 654*459f5d12SBarry Smith if (flg) { 655*459f5d12SBarry Smith PetscViewer ctx; 656e24b481bSBarry Smith 657*459f5d12SBarry Smith ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&ctx);CHKERRQ(ierr); 658*459f5d12SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 659*459f5d12SBarry Smith } 6602e7541e6SPeter Brune 6612e7541e6SPeter Brune flg = PETSC_FALSE; 6622e7541e6SPeter Brune ierr = PetscOptionsBool("-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 6632e7541e6SPeter Brune if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorJacUpdateSpectrum,0,0);CHKERRQ(ierr);} 6642e7541e6SPeter Brune 66590d69ab7SBarry Smith flg = PETSC_FALSE; 666acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 6674b27c08aSLois Curfman McInnes if (flg) { 6686cab3a1bSJed Brown void *functx; 6696cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 6706cab3a1bSJed Brown ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr); 671ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 6729b94acceSBarry Smith } 673639f9d9dSBarry Smith 67444848bc4SPeter Brune flg = PETSC_FALSE; 67544848bc4SPeter Brune ierr = PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESDefaultComputeJacobianColor",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 67644848bc4SPeter Brune if (flg) { 67744848bc4SPeter Brune void *functx; 67844848bc4SPeter Brune ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 6790171d955SPeter Brune ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobianColor,0);CHKERRQ(ierr); 68044848bc4SPeter Brune ierr = PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr); 68144848bc4SPeter Brune } 68244848bc4SPeter Brune 683aa3661deSLisandro Dalcin flg = PETSC_FALSE; 684d8f46077SPeter Brune ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&snes->mf_operator,&flg);CHKERRQ(ierr); 685d8f46077SPeter Brune if (flg && snes->mf_operator) { 686a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 687d8f46077SPeter Brune snes->mf = PETSC_TRUE; 688a8248277SBarry Smith } 689aa3661deSLisandro Dalcin flg = PETSC_FALSE; 690d8f46077SPeter Brune ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&snes->mf,&flg);CHKERRQ(ierr); 691d8f46077SPeter Brune if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE; 692d8f46077SPeter Brune ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,0);CHKERRQ(ierr); 693d28543b3SPeter Brune 694c40d0f55SPeter Brune flg = PETSC_FALSE; 695c40d0f55SPeter Brune ierr = SNESGetPCSide(snes,&pcside); 696c40d0f55SPeter Brune ierr = PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);CHKERRQ(ierr); 697c40d0f55SPeter Brune if (flg) {ierr = SNESSetPCSide(snes,pcside);CHKERRQ(ierr);} 698c40d0f55SPeter Brune 69989b92e6fSPeter Brune /* GS Options */ 70089b92e6fSPeter Brune ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr); 70189b92e6fSPeter Brune 70276b2cf59SMatthew Knepley for (i = 0; i < numberofsetfromoptions; i++) { 70376b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 70476b2cf59SMatthew Knepley } 70576b2cf59SMatthew Knepley 706e7788613SBarry Smith if (snes->ops->setfromoptions) { 707e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 708639f9d9dSBarry Smith } 7095d973c19SBarry Smith 7105d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 7115d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 712b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 7134bbc92c1SBarry Smith 7141cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 715aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 716aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 71785385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 71893993e2dSLois Curfman McInnes 7199e764e56SPeter Brune if (!snes->linesearch) { 720f1c6b773SPeter Brune ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 7219e764e56SPeter Brune } 722f1c6b773SPeter Brune ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr); 7239e764e56SPeter Brune 72451e86f29SPeter Brune /* if someone has set the SNES PC type, create it. */ 72551e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 72651e86f29SPeter Brune ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 72751e86f29SPeter Brune if (pcset && (!snes->pc)) { 72851e86f29SPeter Brune ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr); 72951e86f29SPeter Brune } 7303a40ed3dSBarry Smith PetscFunctionReturn(0); 7319b94acceSBarry Smith } 7329b94acceSBarry Smith 733d25893d9SBarry Smith #undef __FUNCT__ 734d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 735d25893d9SBarry Smith /*@ 736d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 737d25893d9SBarry Smith the nonlinear solvers. 738d25893d9SBarry Smith 739d25893d9SBarry Smith Logically Collective on SNES 740d25893d9SBarry Smith 741d25893d9SBarry Smith Input Parameters: 742d25893d9SBarry Smith + snes - the SNES context 743d25893d9SBarry Smith . compute - function to compute the context 744d25893d9SBarry Smith - destroy - function to destroy the context 745d25893d9SBarry Smith 746d25893d9SBarry Smith Level: intermediate 747d25893d9SBarry Smith 748d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 749d25893d9SBarry Smith 750d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 751d25893d9SBarry Smith @*/ 752d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 753d25893d9SBarry Smith { 754d25893d9SBarry Smith PetscFunctionBegin; 755d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 756d25893d9SBarry Smith snes->ops->usercompute = compute; 757d25893d9SBarry Smith snes->ops->userdestroy = destroy; 758d25893d9SBarry Smith PetscFunctionReturn(0); 759d25893d9SBarry Smith } 760a847f771SSatish Balay 7614a2ae208SSatish Balay #undef __FUNCT__ 7624a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 763b07ff414SBarry Smith /*@ 7649b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 7659b94acceSBarry Smith the nonlinear solvers. 7669b94acceSBarry Smith 7673f9fe445SBarry Smith Logically Collective on SNES 768fee21e36SBarry Smith 769c7afd0dbSLois Curfman McInnes Input Parameters: 770c7afd0dbSLois Curfman McInnes + snes - the SNES context 771c7afd0dbSLois Curfman McInnes - usrP - optional user context 772c7afd0dbSLois Curfman McInnes 77336851e7fSLois Curfman McInnes Level: intermediate 77436851e7fSLois Curfman McInnes 7759b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 7769b94acceSBarry Smith 777ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext() 7789b94acceSBarry Smith @*/ 7797087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 7809b94acceSBarry Smith { 7811b2093e4SBarry Smith PetscErrorCode ierr; 782b07ff414SBarry Smith KSP ksp; 7831b2093e4SBarry Smith 7843a40ed3dSBarry Smith PetscFunctionBegin; 7850700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 786b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 787b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 7889b94acceSBarry Smith snes->user = usrP; 7893a40ed3dSBarry Smith PetscFunctionReturn(0); 7909b94acceSBarry Smith } 79174679c65SBarry Smith 7924a2ae208SSatish Balay #undef __FUNCT__ 7934a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 794b07ff414SBarry Smith /*@ 7959b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 7969b94acceSBarry Smith nonlinear solvers. 7979b94acceSBarry Smith 798c7afd0dbSLois Curfman McInnes Not Collective 799c7afd0dbSLois Curfman McInnes 8009b94acceSBarry Smith Input Parameter: 8019b94acceSBarry Smith . snes - SNES context 8029b94acceSBarry Smith 8039b94acceSBarry Smith Output Parameter: 8049b94acceSBarry Smith . usrP - user context 8059b94acceSBarry Smith 80636851e7fSLois Curfman McInnes Level: intermediate 80736851e7fSLois Curfman McInnes 8089b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 8099b94acceSBarry Smith 8109b94acceSBarry Smith .seealso: SNESSetApplicationContext() 8119b94acceSBarry Smith @*/ 812e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 8139b94acceSBarry Smith { 8143a40ed3dSBarry Smith PetscFunctionBegin; 8150700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 816e71120c6SJed Brown *(void**)usrP = snes->user; 8173a40ed3dSBarry Smith PetscFunctionReturn(0); 8189b94acceSBarry Smith } 81974679c65SBarry Smith 8204a2ae208SSatish Balay #undef __FUNCT__ 8214a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 8229b94acceSBarry Smith /*@ 823c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 824c8228a4eSBarry Smith at this time. 8259b94acceSBarry Smith 826c7afd0dbSLois Curfman McInnes Not Collective 827c7afd0dbSLois Curfman McInnes 8289b94acceSBarry Smith Input Parameter: 8299b94acceSBarry Smith . snes - SNES context 8309b94acceSBarry Smith 8319b94acceSBarry Smith Output Parameter: 8329b94acceSBarry Smith . iter - iteration number 8339b94acceSBarry Smith 834c8228a4eSBarry Smith Notes: 835c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 836c8228a4eSBarry Smith 837c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 83808405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 83908405cd6SLois Curfman McInnes .vb 84008405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 84108405cd6SLois Curfman McInnes if (!(it % 2)) { 84208405cd6SLois Curfman McInnes [compute Jacobian here] 84308405cd6SLois Curfman McInnes } 84408405cd6SLois Curfman McInnes .ve 845c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 84608405cd6SLois Curfman McInnes recomputed every second SNES iteration. 847c8228a4eSBarry Smith 84836851e7fSLois Curfman McInnes Level: intermediate 84936851e7fSLois Curfman McInnes 8502b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 8512b668275SBarry Smith 852b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 8539b94acceSBarry Smith @*/ 8547087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 8559b94acceSBarry Smith { 8563a40ed3dSBarry Smith PetscFunctionBegin; 8570700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8584482741eSBarry Smith PetscValidIntPointer(iter,2); 8599b94acceSBarry Smith *iter = snes->iter; 8603a40ed3dSBarry Smith PetscFunctionReturn(0); 8619b94acceSBarry Smith } 86274679c65SBarry Smith 8634a2ae208SSatish Balay #undef __FUNCT__ 864360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber" 865360c497dSPeter Brune /*@ 866360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 867360c497dSPeter Brune 868360c497dSPeter Brune Not Collective 869360c497dSPeter Brune 870360c497dSPeter Brune Input Parameter: 871360c497dSPeter Brune . snes - SNES context 872360c497dSPeter Brune . iter - iteration number 873360c497dSPeter Brune 874360c497dSPeter Brune Level: developer 875360c497dSPeter Brune 876360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number, 877360c497dSPeter Brune 878360c497dSPeter Brune .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 879360c497dSPeter Brune @*/ 880360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 881360c497dSPeter Brune { 882360c497dSPeter Brune PetscErrorCode ierr; 883360c497dSPeter Brune 884360c497dSPeter Brune PetscFunctionBegin; 885360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 886360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 887360c497dSPeter Brune snes->iter = iter; 888360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 889360c497dSPeter Brune PetscFunctionReturn(0); 890360c497dSPeter Brune } 891360c497dSPeter Brune 892360c497dSPeter Brune #undef __FUNCT__ 8934a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 8949b94acceSBarry Smith /*@ 8959b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 8969b94acceSBarry Smith with SNESSSetFunction(). 8979b94acceSBarry Smith 898c7afd0dbSLois Curfman McInnes Collective on SNES 899c7afd0dbSLois Curfman McInnes 9009b94acceSBarry Smith Input Parameter: 9019b94acceSBarry Smith . snes - SNES context 9029b94acceSBarry Smith 9039b94acceSBarry Smith Output Parameter: 9049b94acceSBarry Smith . fnorm - 2-norm of function 9059b94acceSBarry Smith 90636851e7fSLois Curfman McInnes Level: intermediate 90736851e7fSLois Curfman McInnes 9089b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 909a86d99e1SLois Curfman McInnes 910b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 9119b94acceSBarry Smith @*/ 9127087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 9139b94acceSBarry Smith { 9143a40ed3dSBarry Smith PetscFunctionBegin; 9150700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9164482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 9179b94acceSBarry Smith *fnorm = snes->norm; 9183a40ed3dSBarry Smith PetscFunctionReturn(0); 9199b94acceSBarry Smith } 92074679c65SBarry Smith 921360c497dSPeter Brune 922360c497dSPeter Brune #undef __FUNCT__ 923360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm" 924360c497dSPeter Brune /*@ 925360c497dSPeter Brune SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm(). 926360c497dSPeter Brune 927360c497dSPeter Brune Collective on SNES 928360c497dSPeter Brune 929360c497dSPeter Brune Input Parameter: 930360c497dSPeter Brune . snes - SNES context 931360c497dSPeter Brune . fnorm - 2-norm of function 932360c497dSPeter Brune 933360c497dSPeter Brune Level: developer 934360c497dSPeter Brune 935360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm 936360c497dSPeter Brune 937360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm(). 938360c497dSPeter Brune @*/ 939360c497dSPeter Brune PetscErrorCode SNESSetFunctionNorm(SNES snes,PetscReal fnorm) 940360c497dSPeter Brune { 941360c497dSPeter Brune 942360c497dSPeter Brune PetscErrorCode ierr; 943360c497dSPeter Brune 944360c497dSPeter Brune PetscFunctionBegin; 945360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 946360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 947360c497dSPeter Brune snes->norm = fnorm; 948360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 949360c497dSPeter Brune PetscFunctionReturn(0); 950360c497dSPeter Brune } 951360c497dSPeter Brune 9524a2ae208SSatish Balay #undef __FUNCT__ 953b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 9549b94acceSBarry Smith /*@ 955b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 9569b94acceSBarry Smith attempted by the nonlinear solver. 9579b94acceSBarry Smith 958c7afd0dbSLois Curfman McInnes Not Collective 959c7afd0dbSLois Curfman McInnes 9609b94acceSBarry Smith Input Parameter: 9619b94acceSBarry Smith . snes - SNES context 9629b94acceSBarry Smith 9639b94acceSBarry Smith Output Parameter: 9649b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 9659b94acceSBarry Smith 966c96a6f78SLois Curfman McInnes Notes: 967c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 968c96a6f78SLois Curfman McInnes 96936851e7fSLois Curfman McInnes Level: intermediate 97036851e7fSLois Curfman McInnes 9719b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 97258ebbce7SBarry Smith 973e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 97458ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 9759b94acceSBarry Smith @*/ 9767087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 9779b94acceSBarry Smith { 9783a40ed3dSBarry Smith PetscFunctionBegin; 9790700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9804482741eSBarry Smith PetscValidIntPointer(nfails,2); 98150ffb88aSMatthew Knepley *nfails = snes->numFailures; 98250ffb88aSMatthew Knepley PetscFunctionReturn(0); 98350ffb88aSMatthew Knepley } 98450ffb88aSMatthew Knepley 98550ffb88aSMatthew Knepley #undef __FUNCT__ 986b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 98750ffb88aSMatthew Knepley /*@ 988b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 98950ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 99050ffb88aSMatthew Knepley 99150ffb88aSMatthew Knepley Not Collective 99250ffb88aSMatthew Knepley 99350ffb88aSMatthew Knepley Input Parameters: 99450ffb88aSMatthew Knepley + snes - SNES context 99550ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 99650ffb88aSMatthew Knepley 99750ffb88aSMatthew Knepley Level: intermediate 99850ffb88aSMatthew Knepley 99950ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 100058ebbce7SBarry Smith 1001e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 100258ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 100350ffb88aSMatthew Knepley @*/ 10047087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 100550ffb88aSMatthew Knepley { 100650ffb88aSMatthew Knepley PetscFunctionBegin; 10070700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 100850ffb88aSMatthew Knepley snes->maxFailures = maxFails; 100950ffb88aSMatthew Knepley PetscFunctionReturn(0); 101050ffb88aSMatthew Knepley } 101150ffb88aSMatthew Knepley 101250ffb88aSMatthew Knepley #undef __FUNCT__ 1013b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 101450ffb88aSMatthew Knepley /*@ 1015b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 101650ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 101750ffb88aSMatthew Knepley 101850ffb88aSMatthew Knepley Not Collective 101950ffb88aSMatthew Knepley 102050ffb88aSMatthew Knepley Input Parameter: 102150ffb88aSMatthew Knepley . snes - SNES context 102250ffb88aSMatthew Knepley 102350ffb88aSMatthew Knepley Output Parameter: 102450ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 102550ffb88aSMatthew Knepley 102650ffb88aSMatthew Knepley Level: intermediate 102750ffb88aSMatthew Knepley 102850ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 102958ebbce7SBarry Smith 1030e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 103158ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 103258ebbce7SBarry Smith 103350ffb88aSMatthew Knepley @*/ 10347087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 103550ffb88aSMatthew Knepley { 103650ffb88aSMatthew Knepley PetscFunctionBegin; 10370700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10384482741eSBarry Smith PetscValidIntPointer(maxFails,2); 103950ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 10403a40ed3dSBarry Smith PetscFunctionReturn(0); 10419b94acceSBarry Smith } 1042a847f771SSatish Balay 10434a2ae208SSatish Balay #undef __FUNCT__ 10442541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 10452541af92SBarry Smith /*@ 10462541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 10472541af92SBarry Smith done by SNES. 10482541af92SBarry Smith 10492541af92SBarry Smith Not Collective 10502541af92SBarry Smith 10512541af92SBarry Smith Input Parameter: 10522541af92SBarry Smith . snes - SNES context 10532541af92SBarry Smith 10542541af92SBarry Smith Output Parameter: 10552541af92SBarry Smith . nfuncs - number of evaluations 10562541af92SBarry Smith 10572541af92SBarry Smith Level: intermediate 10582541af92SBarry Smith 10592541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 106058ebbce7SBarry Smith 1061e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 10622541af92SBarry Smith @*/ 10637087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 10642541af92SBarry Smith { 10652541af92SBarry Smith PetscFunctionBegin; 10660700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10672541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 10682541af92SBarry Smith *nfuncs = snes->nfuncs; 10692541af92SBarry Smith PetscFunctionReturn(0); 10702541af92SBarry Smith } 10712541af92SBarry Smith 10722541af92SBarry Smith #undef __FUNCT__ 10733d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 10743d4c4710SBarry Smith /*@ 10753d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 10763d4c4710SBarry Smith linear solvers. 10773d4c4710SBarry Smith 10783d4c4710SBarry Smith Not Collective 10793d4c4710SBarry Smith 10803d4c4710SBarry Smith Input Parameter: 10813d4c4710SBarry Smith . snes - SNES context 10823d4c4710SBarry Smith 10833d4c4710SBarry Smith Output Parameter: 10843d4c4710SBarry Smith . nfails - number of failed solves 10853d4c4710SBarry Smith 10863d4c4710SBarry Smith Notes: 10873d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 10883d4c4710SBarry Smith 10893d4c4710SBarry Smith Level: intermediate 10903d4c4710SBarry Smith 10913d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 109258ebbce7SBarry Smith 1093e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 10943d4c4710SBarry Smith @*/ 10957087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 10963d4c4710SBarry Smith { 10973d4c4710SBarry Smith PetscFunctionBegin; 10980700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10993d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 11003d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 11013d4c4710SBarry Smith PetscFunctionReturn(0); 11023d4c4710SBarry Smith } 11033d4c4710SBarry Smith 11043d4c4710SBarry Smith #undef __FUNCT__ 11053d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 11063d4c4710SBarry Smith /*@ 11073d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 11083d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 11093d4c4710SBarry Smith 11103f9fe445SBarry Smith Logically Collective on SNES 11113d4c4710SBarry Smith 11123d4c4710SBarry Smith Input Parameters: 11133d4c4710SBarry Smith + snes - SNES context 11143d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 11153d4c4710SBarry Smith 11163d4c4710SBarry Smith Level: intermediate 11173d4c4710SBarry Smith 1118a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 11193d4c4710SBarry Smith 11203d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 11213d4c4710SBarry Smith 112258ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 11233d4c4710SBarry Smith @*/ 11247087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 11253d4c4710SBarry Smith { 11263d4c4710SBarry Smith PetscFunctionBegin; 11270700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1128c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 11293d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 11303d4c4710SBarry Smith PetscFunctionReturn(0); 11313d4c4710SBarry Smith } 11323d4c4710SBarry Smith 11333d4c4710SBarry Smith #undef __FUNCT__ 11343d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 11353d4c4710SBarry Smith /*@ 11363d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 11373d4c4710SBarry Smith are allowed before SNES terminates 11383d4c4710SBarry Smith 11393d4c4710SBarry Smith Not Collective 11403d4c4710SBarry Smith 11413d4c4710SBarry Smith Input Parameter: 11423d4c4710SBarry Smith . snes - SNES context 11433d4c4710SBarry Smith 11443d4c4710SBarry Smith Output Parameter: 11453d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 11463d4c4710SBarry Smith 11473d4c4710SBarry Smith Level: intermediate 11483d4c4710SBarry Smith 11493d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 11503d4c4710SBarry Smith 11513d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 11523d4c4710SBarry Smith 1153e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 11543d4c4710SBarry Smith @*/ 11557087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 11563d4c4710SBarry Smith { 11573d4c4710SBarry Smith PetscFunctionBegin; 11580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11593d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 11603d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 11613d4c4710SBarry Smith PetscFunctionReturn(0); 11623d4c4710SBarry Smith } 11633d4c4710SBarry Smith 11643d4c4710SBarry Smith #undef __FUNCT__ 1165b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 1166c96a6f78SLois Curfman McInnes /*@ 1167b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1168c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1169c96a6f78SLois Curfman McInnes 1170c7afd0dbSLois Curfman McInnes Not Collective 1171c7afd0dbSLois Curfman McInnes 1172c96a6f78SLois Curfman McInnes Input Parameter: 1173c96a6f78SLois Curfman McInnes . snes - SNES context 1174c96a6f78SLois Curfman McInnes 1175c96a6f78SLois Curfman McInnes Output Parameter: 1176c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1177c96a6f78SLois Curfman McInnes 1178c96a6f78SLois Curfman McInnes Notes: 1179c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1180c96a6f78SLois Curfman McInnes 118136851e7fSLois Curfman McInnes Level: intermediate 118236851e7fSLois Curfman McInnes 1183c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 11842b668275SBarry Smith 11858c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 1186c96a6f78SLois Curfman McInnes @*/ 11877087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 1188c96a6f78SLois Curfman McInnes { 11893a40ed3dSBarry Smith PetscFunctionBegin; 11900700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11914482741eSBarry Smith PetscValidIntPointer(lits,2); 1192c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 11933a40ed3dSBarry Smith PetscFunctionReturn(0); 1194c96a6f78SLois Curfman McInnes } 1195c96a6f78SLois Curfman McInnes 11964a2ae208SSatish Balay #undef __FUNCT__ 119794b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 119852baeb72SSatish Balay /*@ 119994b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 12009b94acceSBarry Smith 120194b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 1202c7afd0dbSLois Curfman McInnes 12039b94acceSBarry Smith Input Parameter: 12049b94acceSBarry Smith . snes - the SNES context 12059b94acceSBarry Smith 12069b94acceSBarry Smith Output Parameter: 120794b7f48cSBarry Smith . ksp - the KSP context 12089b94acceSBarry Smith 12099b94acceSBarry Smith Notes: 121094b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 12119b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 12122999313aSBarry Smith PC contexts as well. 12139b94acceSBarry Smith 121436851e7fSLois Curfman McInnes Level: beginner 121536851e7fSLois Curfman McInnes 121694b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 12179b94acceSBarry Smith 12182999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 12199b94acceSBarry Smith @*/ 12207087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 12219b94acceSBarry Smith { 12221cee3971SBarry Smith PetscErrorCode ierr; 12231cee3971SBarry Smith 12243a40ed3dSBarry Smith PetscFunctionBegin; 12250700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12264482741eSBarry Smith PetscValidPointer(ksp,2); 12271cee3971SBarry Smith 12281cee3971SBarry Smith if (!snes->ksp) { 12291cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 12301cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 12311cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 12321cee3971SBarry Smith } 123394b7f48cSBarry Smith *ksp = snes->ksp; 12343a40ed3dSBarry Smith PetscFunctionReturn(0); 12359b94acceSBarry Smith } 123682bf6240SBarry Smith 12374a2ae208SSatish Balay #undef __FUNCT__ 12382999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 12392999313aSBarry Smith /*@ 12402999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 12412999313aSBarry Smith 12422999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 12432999313aSBarry Smith 12442999313aSBarry Smith Input Parameters: 12452999313aSBarry Smith + snes - the SNES context 12462999313aSBarry Smith - ksp - the KSP context 12472999313aSBarry Smith 12482999313aSBarry Smith Notes: 12492999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 12502999313aSBarry Smith so this routine is rarely needed. 12512999313aSBarry Smith 12522999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 12532999313aSBarry Smith decreased by one. 12542999313aSBarry Smith 12552999313aSBarry Smith Level: developer 12562999313aSBarry Smith 12572999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 12582999313aSBarry Smith 12592999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 12602999313aSBarry Smith @*/ 12617087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 12622999313aSBarry Smith { 12632999313aSBarry Smith PetscErrorCode ierr; 12642999313aSBarry Smith 12652999313aSBarry Smith PetscFunctionBegin; 12660700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12670700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 12682999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 12697dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1270906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 12712999313aSBarry Smith snes->ksp = ksp; 12722999313aSBarry Smith PetscFunctionReturn(0); 12732999313aSBarry Smith } 12742999313aSBarry Smith 12757adad957SLisandro Dalcin #if 0 12762999313aSBarry Smith #undef __FUNCT__ 12774a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 12786849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1279e24b481bSBarry Smith { 1280e24b481bSBarry Smith PetscFunctionBegin; 1281e24b481bSBarry Smith PetscFunctionReturn(0); 1282e24b481bSBarry Smith } 12837adad957SLisandro Dalcin #endif 1284e24b481bSBarry Smith 12859b94acceSBarry Smith /* -----------------------------------------------------------*/ 12864a2ae208SSatish Balay #undef __FUNCT__ 12874a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 128852baeb72SSatish Balay /*@ 12899b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 12909b94acceSBarry Smith 1291c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1292c7afd0dbSLois Curfman McInnes 1293c7afd0dbSLois Curfman McInnes Input Parameters: 1294906ed7ccSBarry Smith . comm - MPI communicator 12959b94acceSBarry Smith 12969b94acceSBarry Smith Output Parameter: 12979b94acceSBarry Smith . outsnes - the new SNES context 12989b94acceSBarry Smith 1299c7afd0dbSLois Curfman McInnes Options Database Keys: 1300c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1301c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1302c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1303c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1304c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1305c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1306c1f60f51SBarry Smith 130736851e7fSLois Curfman McInnes Level: beginner 130836851e7fSLois Curfman McInnes 13099b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 13109b94acceSBarry Smith 1311a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1312a8054027SBarry Smith 13139b94acceSBarry Smith @*/ 13147087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 13159b94acceSBarry Smith { 1316dfbe8321SBarry Smith PetscErrorCode ierr; 13179b94acceSBarry Smith SNES snes; 1318fa9f3622SBarry Smith SNESKSPEW *kctx; 131937fcc0dbSBarry Smith 13203a40ed3dSBarry Smith PetscFunctionBegin; 1321ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 13228ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 13238ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 13248ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 13258ba1e511SMatthew Knepley #endif 13268ba1e511SMatthew Knepley 13273194b578SJed Brown ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 13287adad957SLisandro Dalcin 132985385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 13302c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 133188976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 13329b94acceSBarry Smith snes->max_its = 50; 13339750a799SBarry Smith snes->max_funcs = 10000; 13349b94acceSBarry Smith snes->norm = 0.0; 1335fdacfa88SPeter Brune snes->normtype = SNES_NORM_FUNCTION; 1336b4874afaSBarry Smith snes->rtol = 1.e-8; 1337b4874afaSBarry Smith snes->ttol = 0.0; 133870441072SBarry Smith snes->abstol = 1.e-50; 1339c60f73f4SPeter Brune snes->stol = 1.e-8; 13404b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 13419b94acceSBarry Smith snes->nfuncs = 0; 134250ffb88aSMatthew Knepley snes->numFailures = 0; 134350ffb88aSMatthew Knepley snes->maxFailures = 1; 13447a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1345e35cf81dSBarry Smith snes->lagjacobian = 1; 1346a8054027SBarry Smith snes->lagpreconditioner = 1; 1347639f9d9dSBarry Smith snes->numbermonitors = 0; 13489b94acceSBarry Smith snes->data = 0; 13494dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1350186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 13516f24a144SLois Curfman McInnes snes->nwork = 0; 135258c9b817SLisandro Dalcin snes->work = 0; 135358c9b817SLisandro Dalcin snes->nvwork = 0; 135458c9b817SLisandro Dalcin snes->vwork = 0; 1355758f92a0SBarry Smith snes->conv_hist_len = 0; 1356758f92a0SBarry Smith snes->conv_hist_max = 0; 1357758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1358758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1359758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1360e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1361e4ed7901SPeter Brune snes->norm_init = 0.; 1362e4ed7901SPeter Brune snes->norm_init_set = PETSC_FALSE; 1363184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 136489b92e6fSPeter Brune snes->gssweeps = 1; 13659b94acceSBarry Smith 1366c40d0f55SPeter Brune snes->pcside = PC_RIGHT; 1367c40d0f55SPeter Brune 1368d8f46077SPeter Brune snes->mf = PETSC_FALSE; 1369d8f46077SPeter Brune snes->mf_operator = PETSC_FALSE; 1370d8f46077SPeter Brune snes->mf_version = 1; 1371d8f46077SPeter Brune 13723d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 13733d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 13743d4c4710SBarry Smith 13759b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 137638f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 13779b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 13789b94acceSBarry Smith kctx->version = 2; 13799b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 13809b94acceSBarry Smith this was too large for some test cases */ 138175567043SBarry Smith kctx->rtol_last = 0.0; 13829b94acceSBarry Smith kctx->rtol_max = .9; 13839b94acceSBarry Smith kctx->gamma = 1.0; 138462d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 138571f87433Sdalcinl kctx->alpha2 = kctx->alpha; 13869b94acceSBarry Smith kctx->threshold = .1; 138775567043SBarry Smith kctx->lresid_last = 0.0; 138875567043SBarry Smith kctx->norm_last = 0.0; 13899b94acceSBarry Smith 13909b94acceSBarry Smith *outsnes = snes; 13913a40ed3dSBarry Smith PetscFunctionReturn(0); 13929b94acceSBarry Smith } 13939b94acceSBarry Smith 13944a2ae208SSatish Balay #undef __FUNCT__ 13954a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 13969b94acceSBarry Smith /*@C 13979b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 13989b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 13999b94acceSBarry Smith equations. 14009b94acceSBarry Smith 14013f9fe445SBarry Smith Logically Collective on SNES 1402fee21e36SBarry Smith 1403c7afd0dbSLois Curfman McInnes Input Parameters: 1404c7afd0dbSLois Curfman McInnes + snes - the SNES context 1405c7afd0dbSLois Curfman McInnes . r - vector to store function value 1406de044059SHong Zhang . func - function evaluation routine 1407c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1408c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 14099b94acceSBarry Smith 1410c7afd0dbSLois Curfman McInnes Calling sequence of func: 14118d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1412c7afd0dbSLois Curfman McInnes 1413c586c404SJed Brown + snes - the SNES context 1414c586c404SJed Brown . x - state at which to evaluate residual 1415c586c404SJed Brown . f - vector to put residual 1416c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 14179b94acceSBarry Smith 14189b94acceSBarry Smith Notes: 14199b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 14209b94acceSBarry Smith $ f'(x) x = -f(x), 1421c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 14229b94acceSBarry Smith 142336851e7fSLois Curfman McInnes Level: beginner 142436851e7fSLois Curfman McInnes 14259b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 14269b94acceSBarry Smith 14278b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard() 14289b94acceSBarry Smith @*/ 14297087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 14309b94acceSBarry Smith { 143185385478SLisandro Dalcin PetscErrorCode ierr; 14326cab3a1bSJed Brown DM dm; 14336cab3a1bSJed Brown 14343a40ed3dSBarry Smith PetscFunctionBegin; 14350700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1436d2a683ecSLisandro Dalcin if (r) { 1437d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1438d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 143985385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 14406bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 144185385478SLisandro Dalcin snes->vec_func = r; 1442d2a683ecSLisandro Dalcin } 14436cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 14446cab3a1bSJed Brown ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr); 14453a40ed3dSBarry Smith PetscFunctionReturn(0); 14469b94acceSBarry Smith } 14479b94acceSBarry Smith 1448646217ecSPeter Brune 1449646217ecSPeter Brune #undef __FUNCT__ 1450e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction" 1451e4ed7901SPeter Brune /*@C 1452e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1453e4ed7901SPeter Brune function norm at the initialization of the method. In some 1454e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1455e4ed7901SPeter Brune SNESSolve. This function allows one to avoid a redundant call 1456e4ed7901SPeter Brune to SNESComputeFunction in that case. 1457e4ed7901SPeter Brune 1458e4ed7901SPeter Brune Logically Collective on SNES 1459e4ed7901SPeter Brune 1460e4ed7901SPeter Brune Input Parameters: 1461e4ed7901SPeter Brune + snes - the SNES context 1462e4ed7901SPeter Brune - f - vector to store function value 1463e4ed7901SPeter Brune 1464e4ed7901SPeter Brune Notes: 1465e4ed7901SPeter Brune This should not be modified during the solution procedure. 1466e4ed7901SPeter Brune 1467e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1468e4ed7901SPeter Brune 1469e4ed7901SPeter Brune Level: developer 1470e4ed7901SPeter Brune 1471e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function 1472e4ed7901SPeter Brune 1473e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm() 1474e4ed7901SPeter Brune @*/ 1475e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1476e4ed7901SPeter Brune { 1477e4ed7901SPeter Brune PetscErrorCode ierr; 1478e4ed7901SPeter Brune Vec vec_func; 1479e4ed7901SPeter Brune 1480e4ed7901SPeter Brune PetscFunctionBegin; 1481e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1482e4ed7901SPeter Brune PetscValidHeaderSpecific(f,VEC_CLASSID,2); 1483e4ed7901SPeter Brune PetscCheckSameComm(snes,1,f,2); 1484e4ed7901SPeter Brune ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1485e4ed7901SPeter Brune ierr = VecCopy(f, vec_func);CHKERRQ(ierr); 1486217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 1487e4ed7901SPeter Brune PetscFunctionReturn(0); 1488e4ed7901SPeter Brune } 1489e4ed7901SPeter Brune 1490e4ed7901SPeter Brune 1491e4ed7901SPeter Brune #undef __FUNCT__ 1492e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm" 1493e4ed7901SPeter Brune /*@C 1494e4ed7901SPeter Brune SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm 1495e4ed7901SPeter Brune at the initialization of the method. In some instances, the user has precomputed 1496e4ed7901SPeter Brune the function and its norm before calling SNESSolve. This function allows one to 1497e4ed7901SPeter Brune avoid a redundant call to SNESComputeFunction() and VecNorm() in that case. 1498e4ed7901SPeter Brune 1499e4ed7901SPeter Brune Logically Collective on SNES 1500e4ed7901SPeter Brune 1501e4ed7901SPeter Brune Input Parameters: 1502e4ed7901SPeter Brune + snes - the SNES context 1503e4ed7901SPeter Brune - fnorm - the norm of F as set by SNESSetInitialFunction() 1504e4ed7901SPeter Brune 1505e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1506e4ed7901SPeter Brune 1507e4ed7901SPeter Brune Level: developer 1508e4ed7901SPeter Brune 1509e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm 1510e4ed7901SPeter Brune 1511e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction() 1512e4ed7901SPeter Brune @*/ 1513e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm) 1514e4ed7901SPeter Brune { 1515e4ed7901SPeter Brune PetscFunctionBegin; 1516e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1517e4ed7901SPeter Brune snes->norm_init = fnorm; 1518e4ed7901SPeter Brune snes->norm_init_set = PETSC_TRUE; 1519e4ed7901SPeter Brune PetscFunctionReturn(0); 1520e4ed7901SPeter Brune } 1521e4ed7901SPeter Brune 1522e4ed7901SPeter Brune #undef __FUNCT__ 1523534ebe21SPeter Brune #define __FUNCT__ "SNESSetNormType" 1524534ebe21SPeter Brune /*@ 1525534ebe21SPeter Brune SNESSetNormType - Sets the SNESNormType used in covergence and monitoring 1526534ebe21SPeter Brune of the SNES method. 1527534ebe21SPeter Brune 1528534ebe21SPeter Brune Logically Collective on SNES 1529534ebe21SPeter Brune 1530534ebe21SPeter Brune Input Parameters: 1531534ebe21SPeter Brune + snes - the SNES context 1532534ebe21SPeter Brune - normtype - the type of the norm used 1533534ebe21SPeter Brune 1534534ebe21SPeter Brune Notes: 1535534ebe21SPeter Brune Only certain SNES methods support certain SNESNormTypes. Most require evaluation 1536534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1537534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1538534ebe21SPeter Brune (SNESGS) and the like do not require the norm of the function to be computed, and therfore 1539534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1540534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1541534ebe21SPeter Brune their solution. 1542534ebe21SPeter Brune 1543534ebe21SPeter Brune Level: developer 1544534ebe21SPeter Brune 1545534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1546534ebe21SPeter Brune 1547534ebe21SPeter Brune .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType 1548534ebe21SPeter Brune @*/ 1549534ebe21SPeter Brune PetscErrorCode SNESSetNormType(SNES snes, SNESNormType normtype) 1550534ebe21SPeter Brune { 1551534ebe21SPeter Brune PetscFunctionBegin; 1552534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1553534ebe21SPeter Brune snes->normtype = normtype; 1554534ebe21SPeter Brune PetscFunctionReturn(0); 1555534ebe21SPeter Brune } 1556534ebe21SPeter Brune 1557534ebe21SPeter Brune 1558534ebe21SPeter Brune #undef __FUNCT__ 1559534ebe21SPeter Brune #define __FUNCT__ "SNESGetNormType" 1560534ebe21SPeter Brune /*@ 1561534ebe21SPeter Brune SNESGetNormType - Gets the SNESNormType used in covergence and monitoring 1562534ebe21SPeter Brune of the SNES method. 1563534ebe21SPeter Brune 1564534ebe21SPeter Brune Logically Collective on SNES 1565534ebe21SPeter Brune 1566534ebe21SPeter Brune Input Parameters: 1567534ebe21SPeter Brune + snes - the SNES context 1568534ebe21SPeter Brune - normtype - the type of the norm used 1569534ebe21SPeter Brune 1570534ebe21SPeter Brune Level: advanced 1571534ebe21SPeter Brune 1572534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1573534ebe21SPeter Brune 1574534ebe21SPeter Brune .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType 1575534ebe21SPeter Brune @*/ 1576534ebe21SPeter Brune PetscErrorCode SNESGetNormType(SNES snes, SNESNormType *normtype) 1577534ebe21SPeter Brune { 1578534ebe21SPeter Brune PetscFunctionBegin; 1579534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1580534ebe21SPeter Brune *normtype = snes->normtype; 1581534ebe21SPeter Brune PetscFunctionReturn(0); 1582534ebe21SPeter Brune } 1583534ebe21SPeter Brune 1584534ebe21SPeter Brune #undef __FUNCT__ 1585646217ecSPeter Brune #define __FUNCT__ "SNESSetGS" 1586c79ef259SPeter Brune /*@C 1587c79ef259SPeter Brune SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for 1588c79ef259SPeter Brune use with composed nonlinear solvers. 1589c79ef259SPeter Brune 1590c79ef259SPeter Brune Input Parameters: 1591c79ef259SPeter Brune + snes - the SNES context 1592c79ef259SPeter Brune . gsfunc - function evaluation routine 1593c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 1594c79ef259SPeter Brune smoother evaluation routine (may be PETSC_NULL) 1595c79ef259SPeter Brune 1596c79ef259SPeter Brune Calling sequence of func: 1597c79ef259SPeter Brune $ func (SNES snes,Vec x,Vec b,void *ctx); 1598c79ef259SPeter Brune 1599c79ef259SPeter Brune + X - solution vector 1600c79ef259SPeter Brune . B - RHS vector 1601d28543b3SPeter Brune - ctx - optional user-defined Gauss-Seidel context 1602c79ef259SPeter Brune 1603c79ef259SPeter Brune Notes: 1604c79ef259SPeter Brune The GS routines are used by the composed nonlinear solver to generate 1605c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1606c79ef259SPeter Brune 1607d28543b3SPeter Brune Level: intermediate 1608c79ef259SPeter Brune 1609d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1610c79ef259SPeter Brune 1611c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS() 1612c79ef259SPeter Brune @*/ 16136cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx) 16146cab3a1bSJed Brown { 16156cab3a1bSJed Brown PetscErrorCode ierr; 16166cab3a1bSJed Brown DM dm; 16176cab3a1bSJed Brown 1618646217ecSPeter Brune PetscFunctionBegin; 16196cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16206cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 16216cab3a1bSJed Brown ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr); 1622646217ecSPeter Brune PetscFunctionReturn(0); 1623646217ecSPeter Brune } 1624646217ecSPeter Brune 1625d25893d9SBarry Smith #undef __FUNCT__ 162689b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps" 162789b92e6fSPeter Brune /*@ 162889b92e6fSPeter Brune SNESSetGSSweeps - Sets the number of sweeps of GS to use. 162989b92e6fSPeter Brune 163089b92e6fSPeter Brune Input Parameters: 163189b92e6fSPeter Brune + snes - the SNES context 163289b92e6fSPeter Brune - sweeps - the number of sweeps of GS to perform. 163389b92e6fSPeter Brune 163489b92e6fSPeter Brune Level: intermediate 163589b92e6fSPeter Brune 163689b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 163789b92e6fSPeter Brune 163889b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps() 163989b92e6fSPeter Brune @*/ 164089b92e6fSPeter Brune 1641c35f09e5SBarry Smith PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) 1642c35f09e5SBarry Smith { 164389b92e6fSPeter Brune PetscFunctionBegin; 164489b92e6fSPeter Brune snes->gssweeps = sweeps; 164589b92e6fSPeter Brune PetscFunctionReturn(0); 164689b92e6fSPeter Brune } 164789b92e6fSPeter Brune 164889b92e6fSPeter Brune 164989b92e6fSPeter Brune #undef __FUNCT__ 165089b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps" 165189b92e6fSPeter Brune /*@ 165289b92e6fSPeter Brune SNESGetGSSweeps - Gets the number of sweeps GS will use. 165389b92e6fSPeter Brune 165489b92e6fSPeter Brune Input Parameters: 165589b92e6fSPeter Brune . snes - the SNES context 165689b92e6fSPeter Brune 165789b92e6fSPeter Brune Output Parameters: 165889b92e6fSPeter Brune . sweeps - the number of sweeps of GS to perform. 165989b92e6fSPeter Brune 166089b92e6fSPeter Brune Level: intermediate 166189b92e6fSPeter Brune 166289b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 166389b92e6fSPeter Brune 166489b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps() 166589b92e6fSPeter Brune @*/ 1666c35f09e5SBarry Smith PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) 1667c35f09e5SBarry Smith { 166889b92e6fSPeter Brune PetscFunctionBegin; 166989b92e6fSPeter Brune *sweeps = snes->gssweeps; 167089b92e6fSPeter Brune PetscFunctionReturn(0); 167189b92e6fSPeter Brune } 167289b92e6fSPeter Brune 167389b92e6fSPeter Brune #undef __FUNCT__ 16748b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 16758b0a5094SBarry Smith PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 16768b0a5094SBarry Smith { 16778b0a5094SBarry Smith PetscErrorCode ierr; 1678e03ab78fSPeter Brune DM dm; 1679e03ab78fSPeter Brune SNESDM sdm; 16806cab3a1bSJed Brown 16818b0a5094SBarry Smith PetscFunctionBegin; 1682e03ab78fSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1683e03ab78fSPeter Brune ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 16848b0a5094SBarry Smith /* A(x)*x - b(x) */ 1685e03ab78fSPeter Brune if (sdm->computepfunction) { 1686e03ab78fSPeter Brune ierr = (*sdm->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr); 1687e03ab78fSPeter Brune } else if (snes->dm) { 1688e03ab78fSPeter Brune ierr = DMComputeFunction(snes->dm,x,f);CHKERRQ(ierr); 1689e03ab78fSPeter Brune } else { 1690e03ab78fSPeter Brune SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() or SNESSetDM() before SNESPicardComputeFunction to provide Picard function."); 1691e03ab78fSPeter Brune } 1692e03ab78fSPeter Brune 1693e03ab78fSPeter Brune if (sdm->computepjacobian) { 1694e03ab78fSPeter Brune ierr = (*sdm->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,sdm->pctx);CHKERRQ(ierr); 1695e03ab78fSPeter Brune } else if (snes->dm) { 1696e03ab78fSPeter Brune ierr = DMComputeJacobian(snes->dm,x,snes->jacobian,snes->jacobian_pre,&snes->matstruct);CHKERRQ(ierr); 1697e03ab78fSPeter Brune } else { 1698e03ab78fSPeter Brune SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() or SNESSetDM() before SNESPicardComputeFunction to provide Picard matrix."); 1699e03ab78fSPeter Brune } 1700e03ab78fSPeter Brune 17018b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 17028b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 17038b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 17048b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 17058b0a5094SBarry Smith PetscFunctionReturn(0); 17068b0a5094SBarry Smith } 17078b0a5094SBarry Smith 17088b0a5094SBarry Smith #undef __FUNCT__ 17098b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 17108b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 17118b0a5094SBarry Smith { 17128b0a5094SBarry Smith PetscFunctionBegin; 1713e03ab78fSPeter Brune /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */ 17148b0a5094SBarry Smith *flag = snes->matstruct; 17158b0a5094SBarry Smith PetscFunctionReturn(0); 17168b0a5094SBarry Smith } 17178b0a5094SBarry Smith 17188b0a5094SBarry Smith #undef __FUNCT__ 17198b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 17208b0a5094SBarry Smith /*@C 17210d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 17228b0a5094SBarry Smith 17238b0a5094SBarry Smith Logically Collective on SNES 17248b0a5094SBarry Smith 17258b0a5094SBarry Smith Input Parameters: 17268b0a5094SBarry Smith + snes - the SNES context 17278b0a5094SBarry Smith . r - vector to store function value 17288b0a5094SBarry Smith . func - function evaluation routine 17298b0a5094SBarry 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) 17308b0a5094SBarry Smith . mat - matrix to store A 17318b0a5094SBarry Smith . mfunc - function to compute matrix value 17328b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 17338b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 17348b0a5094SBarry Smith 17358b0a5094SBarry Smith Calling sequence of func: 17368b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 17378b0a5094SBarry Smith 17388b0a5094SBarry Smith + f - function vector 17398b0a5094SBarry Smith - ctx - optional user-defined function context 17408b0a5094SBarry Smith 17418b0a5094SBarry Smith Calling sequence of mfunc: 17428b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 17438b0a5094SBarry Smith 17448b0a5094SBarry Smith + x - input vector 17458b0a5094SBarry 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(), 17468b0a5094SBarry Smith normally just pass mat in this location 17478b0a5094SBarry Smith . mat - form A(x) matrix 17488b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 17498b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 17508b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 17518b0a5094SBarry Smith 17528b0a5094SBarry Smith Notes: 17538b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 17548b0a5094SBarry Smith 17558b0a5094SBarry 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} 17568b0a5094SBarry 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. 17578b0a5094SBarry Smith 17588b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 17598b0a5094SBarry Smith 17600d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 17610d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 17628b0a5094SBarry Smith 17638b0a5094SBarry 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 17648b0a5094SBarry 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 17658b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 17668b0a5094SBarry Smith 17678b0a5094SBarry Smith Level: beginner 17688b0a5094SBarry Smith 17698b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 17708b0a5094SBarry Smith 17710d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard() 17728b0a5094SBarry Smith @*/ 17738b0a5094SBarry 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) 17748b0a5094SBarry Smith { 17758b0a5094SBarry Smith PetscErrorCode ierr; 1776e03ab78fSPeter Brune DM dm; 1777e03ab78fSPeter Brune 17788b0a5094SBarry Smith PetscFunctionBegin; 17798b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1780e03ab78fSPeter Brune ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 1781e03ab78fSPeter Brune ierr = DMSNESSetPicard(dm,func,mfunc,ctx);CHKERRQ(ierr); 17828b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 17838b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 17848b0a5094SBarry Smith PetscFunctionReturn(0); 17858b0a5094SBarry Smith } 17868b0a5094SBarry Smith 17877971a8bfSPeter Brune 17887971a8bfSPeter Brune #undef __FUNCT__ 17897971a8bfSPeter Brune #define __FUNCT__ "SNESGetPicard" 17907971a8bfSPeter Brune /*@C 17917971a8bfSPeter Brune SNESGetPicard - Returns the context for the Picard iteration 17927971a8bfSPeter Brune 17937971a8bfSPeter Brune Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 17947971a8bfSPeter Brune 17957971a8bfSPeter Brune Input Parameter: 17967971a8bfSPeter Brune . snes - the SNES context 17977971a8bfSPeter Brune 17987971a8bfSPeter Brune Output Parameter: 17997971a8bfSPeter Brune + r - the function (or PETSC_NULL) 18007971a8bfSPeter Brune . func - the function (or PETSC_NULL) 18017971a8bfSPeter Brune . jmat - the picard matrix (or PETSC_NULL) 18027971a8bfSPeter Brune . mat - the picard preconditioner matrix (or PETSC_NULL) 18037971a8bfSPeter Brune . mfunc - the function for matrix evaluation (or PETSC_NULL) 18047971a8bfSPeter Brune - ctx - the function context (or PETSC_NULL) 18057971a8bfSPeter Brune 18067971a8bfSPeter Brune Level: advanced 18077971a8bfSPeter Brune 18087971a8bfSPeter Brune .keywords: SNES, nonlinear, get, function 18097971a8bfSPeter Brune 18107971a8bfSPeter Brune .seealso: SNESSetPicard, SNESGetFunction, SNESGetJacobian, SNESGetDM 18117971a8bfSPeter Brune @*/ 18127971a8bfSPeter 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) 18137971a8bfSPeter Brune { 18147971a8bfSPeter Brune PetscErrorCode ierr; 18157971a8bfSPeter Brune DM dm; 18167971a8bfSPeter Brune 18177971a8bfSPeter Brune PetscFunctionBegin; 18187971a8bfSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 18197971a8bfSPeter Brune ierr = SNESGetFunction(snes,r,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 18207971a8bfSPeter Brune ierr = SNESGetJacobian(snes,jmat,mat,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 18217971a8bfSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18227971a8bfSPeter Brune ierr = DMSNESGetPicard(dm,func,mfunc,ctx);CHKERRQ(ierr); 18237971a8bfSPeter Brune PetscFunctionReturn(0); 18247971a8bfSPeter Brune } 18257971a8bfSPeter Brune 18268b0a5094SBarry Smith #undef __FUNCT__ 1827d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1828d25893d9SBarry Smith /*@C 1829d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1830d25893d9SBarry Smith 1831d25893d9SBarry Smith Logically Collective on SNES 1832d25893d9SBarry Smith 1833d25893d9SBarry Smith Input Parameters: 1834d25893d9SBarry Smith + snes - the SNES context 1835d25893d9SBarry Smith . func - function evaluation routine 1836d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1837d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1838d25893d9SBarry Smith 1839d25893d9SBarry Smith Calling sequence of func: 1840d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1841d25893d9SBarry Smith 1842d25893d9SBarry Smith . f - function vector 1843d25893d9SBarry Smith - ctx - optional user-defined function context 1844d25893d9SBarry Smith 1845d25893d9SBarry Smith Level: intermediate 1846d25893d9SBarry Smith 1847d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1848d25893d9SBarry Smith 1849d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1850d25893d9SBarry Smith @*/ 1851d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1852d25893d9SBarry Smith { 1853d25893d9SBarry Smith PetscFunctionBegin; 1854d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1855d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1856d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1857d25893d9SBarry Smith PetscFunctionReturn(0); 1858d25893d9SBarry Smith } 1859d25893d9SBarry Smith 18603ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 18613ab0aad5SBarry Smith #undef __FUNCT__ 18621096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 18631096aae1SMatthew Knepley /*@C 18641096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 18651096aae1SMatthew Knepley it assumes a zero right hand side. 18661096aae1SMatthew Knepley 18673f9fe445SBarry Smith Logically Collective on SNES 18681096aae1SMatthew Knepley 18691096aae1SMatthew Knepley Input Parameter: 18701096aae1SMatthew Knepley . snes - the SNES context 18711096aae1SMatthew Knepley 18721096aae1SMatthew Knepley Output Parameter: 1873bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 18741096aae1SMatthew Knepley 18751096aae1SMatthew Knepley Level: intermediate 18761096aae1SMatthew Knepley 18771096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 18781096aae1SMatthew Knepley 187985385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 18801096aae1SMatthew Knepley @*/ 18817087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 18821096aae1SMatthew Knepley { 18831096aae1SMatthew Knepley PetscFunctionBegin; 18840700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 18851096aae1SMatthew Knepley PetscValidPointer(rhs,2); 188685385478SLisandro Dalcin *rhs = snes->vec_rhs; 18871096aae1SMatthew Knepley PetscFunctionReturn(0); 18881096aae1SMatthew Knepley } 18891096aae1SMatthew Knepley 18901096aae1SMatthew Knepley #undef __FUNCT__ 18914a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 18929b94acceSBarry Smith /*@ 189336851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 18949b94acceSBarry Smith SNESSetFunction(). 18959b94acceSBarry Smith 1896c7afd0dbSLois Curfman McInnes Collective on SNES 1897c7afd0dbSLois Curfman McInnes 18989b94acceSBarry Smith Input Parameters: 1899c7afd0dbSLois Curfman McInnes + snes - the SNES context 1900c7afd0dbSLois Curfman McInnes - x - input vector 19019b94acceSBarry Smith 19029b94acceSBarry Smith Output Parameter: 19033638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 19049b94acceSBarry Smith 19051bffabb2SLois Curfman McInnes Notes: 190636851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 190736851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 190836851e7fSLois Curfman McInnes themselves. 190936851e7fSLois Curfman McInnes 191036851e7fSLois Curfman McInnes Level: developer 191136851e7fSLois Curfman McInnes 19129b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 19139b94acceSBarry Smith 1914a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 19159b94acceSBarry Smith @*/ 19167087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 19179b94acceSBarry Smith { 1918dfbe8321SBarry Smith PetscErrorCode ierr; 19196cab3a1bSJed Brown DM dm; 19206cab3a1bSJed Brown SNESDM sdm; 19219b94acceSBarry Smith 19223a40ed3dSBarry Smith PetscFunctionBegin; 19230700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 19240700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 19250700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1926c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1927c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 19284ec14c9cSBarry Smith VecValidValues(x,2,PETSC_TRUE); 1929184914b5SBarry Smith 19306cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 19316cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 1932d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 1933c40d0f55SPeter Brune if (snes->pc && snes->pcside == PC_LEFT) { 1934c40d0f55SPeter Brune ierr = VecCopy(x,y);CHKERRQ(ierr); 1935c40d0f55SPeter Brune ierr = SNESSolve(snes->pc,snes->vec_rhs,y);CHKERRQ(ierr); 1936c40d0f55SPeter Brune ierr = VecAYPX(y,-1.0,x);CHKERRQ(ierr); 1937c40d0f55SPeter Brune } else if (sdm->computefunction) { 1938d64ed03dSBarry Smith PetscStackPush("SNES user function"); 19396cab3a1bSJed Brown ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 1940d64ed03dSBarry Smith PetscStackPop; 194173250ac0SBarry Smith } else if (snes->dm) { 1942644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1943c90fad12SPeter Brune } else if (snes->vec_rhs) { 1944c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1945644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 194685385478SLisandro Dalcin if (snes->vec_rhs) { 194785385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 19483ab0aad5SBarry Smith } 1949ae3c334cSLois Curfman McInnes snes->nfuncs++; 1950d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 19514ec14c9cSBarry Smith VecValidValues(y,3,PETSC_FALSE); 19523a40ed3dSBarry Smith PetscFunctionReturn(0); 19539b94acceSBarry Smith } 19549b94acceSBarry Smith 19554a2ae208SSatish Balay #undef __FUNCT__ 1956646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1957c79ef259SPeter Brune /*@ 1958c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1959c79ef259SPeter Brune SNESSetGS(). 1960c79ef259SPeter Brune 1961c79ef259SPeter Brune Collective on SNES 1962c79ef259SPeter Brune 1963c79ef259SPeter Brune Input Parameters: 1964c79ef259SPeter Brune + snes - the SNES context 1965c79ef259SPeter Brune . x - input vector 1966c79ef259SPeter Brune - b - rhs vector 1967c79ef259SPeter Brune 1968c79ef259SPeter Brune Output Parameter: 1969c79ef259SPeter Brune . x - new solution vector 1970c79ef259SPeter Brune 1971c79ef259SPeter Brune Notes: 1972c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1973c79ef259SPeter Brune implementations, so most users would not generally call this routine 1974c79ef259SPeter Brune themselves. 1975c79ef259SPeter Brune 1976c79ef259SPeter Brune Level: developer 1977c79ef259SPeter Brune 1978c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1979c79ef259SPeter Brune 1980c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1981c79ef259SPeter Brune @*/ 1982646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1983646217ecSPeter Brune { 1984646217ecSPeter Brune PetscErrorCode ierr; 198589b92e6fSPeter Brune PetscInt i; 19866cab3a1bSJed Brown DM dm; 19876cab3a1bSJed Brown SNESDM sdm; 1988646217ecSPeter Brune 1989646217ecSPeter Brune PetscFunctionBegin; 1990646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1991646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1992646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1993646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 1994646217ecSPeter Brune if (b) PetscCheckSameComm(snes,1,b,3); 19954ec14c9cSBarry Smith if (b) VecValidValues(b,2,PETSC_TRUE); 1996701cf23dSPeter Brune ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 19976cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 19986cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 19996cab3a1bSJed Brown if (sdm->computegs) { 200089b92e6fSPeter Brune for (i = 0; i < snes->gssweeps; i++) { 2001646217ecSPeter Brune PetscStackPush("SNES user GS"); 20026cab3a1bSJed Brown ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 2003646217ecSPeter Brune PetscStackPop; 200489b92e6fSPeter Brune } 2005646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 2006701cf23dSPeter Brune ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 20074ec14c9cSBarry Smith VecValidValues(x,3,PETSC_FALSE); 2008646217ecSPeter Brune PetscFunctionReturn(0); 2009646217ecSPeter Brune } 2010646217ecSPeter Brune 2011646217ecSPeter Brune 2012646217ecSPeter Brune #undef __FUNCT__ 20134a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 201462fef451SLois Curfman McInnes /*@ 201562fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 201662fef451SLois Curfman McInnes set with SNESSetJacobian(). 201762fef451SLois Curfman McInnes 2018c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 2019c7afd0dbSLois Curfman McInnes 202062fef451SLois Curfman McInnes Input Parameters: 2021c7afd0dbSLois Curfman McInnes + snes - the SNES context 2022c7afd0dbSLois Curfman McInnes - x - input vector 202362fef451SLois Curfman McInnes 202462fef451SLois Curfman McInnes Output Parameters: 2025c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 202662fef451SLois Curfman McInnes . B - optional preconditioning matrix 20272b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 2028fee21e36SBarry Smith 2029e35cf81dSBarry Smith Options Database Keys: 2030e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 2031693365a8SJed Brown . -snes_lag_jacobian <lag> 2032693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 2033693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 2034693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 20354c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 2036c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 2037c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 2038c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 2039c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2040c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 20414c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 2042c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 2043c01495d3SJed Brown 2044e35cf81dSBarry Smith 204562fef451SLois Curfman McInnes Notes: 204662fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 204762fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 204862fef451SLois Curfman McInnes 204994b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 2050dc5a77f8SLois Curfman McInnes flag parameter. 205162fef451SLois Curfman McInnes 205236851e7fSLois Curfman McInnes Level: developer 205336851e7fSLois Curfman McInnes 205462fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 205562fef451SLois Curfman McInnes 2056e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 205762fef451SLois Curfman McInnes @*/ 20587087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 20599b94acceSBarry Smith { 2060dfbe8321SBarry Smith PetscErrorCode ierr; 2061ace3abfcSBarry Smith PetscBool flag; 20626cab3a1bSJed Brown DM dm; 20636cab3a1bSJed Brown SNESDM sdm; 20643a40ed3dSBarry Smith 20653a40ed3dSBarry Smith PetscFunctionBegin; 20660700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 20670700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 20684482741eSBarry Smith PetscValidPointer(flg,5); 2069c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 20704ec14c9cSBarry Smith VecValidValues(X,2,PETSC_TRUE); 20716cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 20726cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 20733232da50SPeter Brune 20746cab3a1bSJed Brown if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 2075ebd3b9afSBarry Smith 2076ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 2077ebd3b9afSBarry Smith 2078fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 2079fe3ffe1eSBarry Smith snes->lagjacobian = -1; 2080fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 2081fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 2082e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 2083e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 2084251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 2085ebd3b9afSBarry Smith if (flag) { 2086ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2087ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2088ebd3b9afSBarry Smith } 2089e35cf81dSBarry Smith PetscFunctionReturn(0); 2090e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 2091e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 2092e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 2093251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 2094ebd3b9afSBarry Smith if (flag) { 2095ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2096ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2097ebd3b9afSBarry Smith } 2098e35cf81dSBarry Smith PetscFunctionReturn(0); 2099e35cf81dSBarry Smith } 2100e35cf81dSBarry Smith 2101c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 2102e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 21033232da50SPeter Brune 2104d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 21053232da50SPeter Brune if (snes->mf && !snes->mf_operator) { 21063232da50SPeter Brune ierr = MatMFFDComputeJacobian(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr); 21073232da50SPeter Brune } else { 21086cab3a1bSJed Brown ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr); 21093232da50SPeter Brune } 2110d64ed03dSBarry Smith PetscStackPop; 21113232da50SPeter Brune 2112d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 2113a8054027SBarry Smith 21143b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 21153b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 21163b4f5425SBarry Smith snes->lagpreconditioner = -1; 21173b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 2118a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 2119a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 2120a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 2121a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 2122a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 2123a8054027SBarry Smith } 2124a8054027SBarry Smith 21256d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 21260700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 21270700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 2128693365a8SJed Brown { 2129693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 2130693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 2131693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 2132693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 2133693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 2134693365a8SJed Brown if (flag || flag_draw || flag_contour) { 2135693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 2136693365a8SJed Brown MatStructure mstruct; 2137693365a8SJed Brown PetscViewer vdraw,vstdout; 21386b3a5b13SJed Brown PetscBool flg; 2139693365a8SJed Brown if (flag_operator) { 2140693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 2141693365a8SJed Brown Bexp = Bexp_mine; 2142693365a8SJed Brown } else { 2143693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 2144251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 2145693365a8SJed Brown if (flg) Bexp = *B; 2146693365a8SJed Brown else { 2147693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 2148693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 2149693365a8SJed Brown Bexp = Bexp_mine; 2150693365a8SJed Brown } 2151693365a8SJed Brown } 2152693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 2153693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 2154693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 2155693365a8SJed Brown if (flag_draw || flag_contour) { 2156693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2157693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 2158693365a8SJed Brown } else vdraw = PETSC_NULL; 2159693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 2160693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 2161693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 2162693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 2163693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2164693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 2165693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2166693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 2167693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2168693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 2169693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2170693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 2171693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2172693365a8SJed Brown } 2173693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2174693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2175693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 2176693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 2177693365a8SJed Brown } 2178693365a8SJed Brown } 21794c30e9fbSJed Brown { 21806719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 21816719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 21824c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 21836719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 21844c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 21854c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 21866719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 21876719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 21886719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 21896719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 21904c30e9fbSJed Brown Mat Bfd; 21914c30e9fbSJed Brown MatStructure mstruct; 21924c30e9fbSJed Brown PetscViewer vdraw,vstdout; 21934c30e9fbSJed Brown ISColoring iscoloring; 21944c30e9fbSJed Brown MatFDColoring matfdcoloring; 21954c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 21964c30e9fbSJed Brown void *funcctx; 21976719d8e4SJed Brown PetscReal norm1,norm2,normmax; 21984c30e9fbSJed Brown 21994c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 22004c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 22014c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 22024c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 22034c30e9fbSJed Brown 22044c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 22054c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 22064c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 22074c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 22084c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 22094c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 22104c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 22114c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 22124c30e9fbSJed Brown 22134c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 22144c30e9fbSJed Brown if (flag_draw || flag_contour) { 22154c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 22164c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 22174c30e9fbSJed Brown } else vdraw = PETSC_NULL; 22184c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 22196719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 22204c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 22214c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 22226719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 22234c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 22244c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 22254c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 22266719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 22274c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 22286719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 22296719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 22304c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 22314c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 22324c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 22334c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 22344c30e9fbSJed Brown } 22354c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 22366719d8e4SJed Brown 22376719d8e4SJed Brown if (flag_threshold) { 22386719d8e4SJed Brown PetscInt bs,rstart,rend,i; 22396719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 22406719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 22416719d8e4SJed Brown for (i=rstart; i<rend; i++) { 22426719d8e4SJed Brown const PetscScalar *ba,*ca; 22436719d8e4SJed Brown const PetscInt *bj,*cj; 22446719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 22456719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 22466719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 22476719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 22486719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 22496719d8e4SJed Brown for (j=0; j<bn; j++) { 22506719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 22516719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 22526719d8e4SJed Brown maxentrycol = bj[j]; 22536719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 22546719d8e4SJed Brown } 22556719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 22566719d8e4SJed Brown maxdiffcol = bj[j]; 22576719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 22586719d8e4SJed Brown } 22596719d8e4SJed Brown if (rdiff > maxrdiff) { 22606719d8e4SJed Brown maxrdiffcol = bj[j]; 22616719d8e4SJed Brown maxrdiff = rdiff; 22626719d8e4SJed Brown } 22636719d8e4SJed Brown } 22646719d8e4SJed Brown if (maxrdiff > 1) { 22656719d8e4SJed 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); 22666719d8e4SJed Brown for (j=0; j<bn; j++) { 22676719d8e4SJed Brown PetscReal rdiff; 22686719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 22696719d8e4SJed Brown if (rdiff > 1) { 22706719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 22716719d8e4SJed Brown } 22726719d8e4SJed Brown } 22736719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 22746719d8e4SJed Brown } 22756719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 22766719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 22776719d8e4SJed Brown } 22786719d8e4SJed Brown } 22794c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 22804c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 22814c30e9fbSJed Brown } 22824c30e9fbSJed Brown } 22833a40ed3dSBarry Smith PetscFunctionReturn(0); 22849b94acceSBarry Smith } 22859b94acceSBarry Smith 22864a2ae208SSatish Balay #undef __FUNCT__ 22874a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 22889b94acceSBarry Smith /*@C 22899b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2290044dda88SLois Curfman McInnes location to store the matrix. 22919b94acceSBarry Smith 22923f9fe445SBarry Smith Logically Collective on SNES and Mat 2293c7afd0dbSLois Curfman McInnes 22949b94acceSBarry Smith Input Parameters: 2295c7afd0dbSLois Curfman McInnes + snes - the SNES context 22969b94acceSBarry Smith . A - Jacobian matrix 22979b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 2298efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 2299c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 2300efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 23019b94acceSBarry Smith 23029b94acceSBarry Smith Calling sequence of func: 23038d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 23049b94acceSBarry Smith 2305c7afd0dbSLois Curfman McInnes + x - input vector 23069b94acceSBarry Smith . A - Jacobian matrix 23079b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 2308ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 23092b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 2310c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 23119b94acceSBarry Smith 23129b94acceSBarry Smith Notes: 231394b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 23142cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 2315ac21db08SLois Curfman McInnes 2316ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 23179b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 23189b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 23199b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 23209b94acceSBarry Smith throughout the global iterations. 23219b94acceSBarry Smith 232216913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 232316913363SBarry Smith each matrix. 232416913363SBarry Smith 2325a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 2326a8a26c1eSJed Brown must be a MatFDColoring. 2327a8a26c1eSJed Brown 2328c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2329c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2330c3cc8fd1SJed Brown 233136851e7fSLois Curfman McInnes Level: beginner 233236851e7fSLois Curfman McInnes 23339b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 23349b94acceSBarry Smith 23353ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 23369b94acceSBarry Smith @*/ 23377087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 23389b94acceSBarry Smith { 2339dfbe8321SBarry Smith PetscErrorCode ierr; 23406cab3a1bSJed Brown DM dm; 23413a7fca6bSBarry Smith 23423a40ed3dSBarry Smith PetscFunctionBegin; 23430700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23440700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 23450700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 2346c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 234706975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 23486cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 23496cab3a1bSJed Brown ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr); 23503a7fca6bSBarry Smith if (A) { 23517dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 23526bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 23539b94acceSBarry Smith snes->jacobian = A; 23543a7fca6bSBarry Smith } 23553a7fca6bSBarry Smith if (B) { 23567dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 23576bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 23589b94acceSBarry Smith snes->jacobian_pre = B; 23593a7fca6bSBarry Smith } 23603a40ed3dSBarry Smith PetscFunctionReturn(0); 23619b94acceSBarry Smith } 236262fef451SLois Curfman McInnes 23634a2ae208SSatish Balay #undef __FUNCT__ 23644a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 2365c2aafc4cSSatish Balay /*@C 2366b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2367b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2368b4fd4287SBarry Smith 2369c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2370c7afd0dbSLois Curfman McInnes 2371b4fd4287SBarry Smith Input Parameter: 2372b4fd4287SBarry Smith . snes - the nonlinear solver context 2373b4fd4287SBarry Smith 2374b4fd4287SBarry Smith Output Parameters: 2375c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 2376b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 237770e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 237870e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 2379fee21e36SBarry Smith 238036851e7fSLois Curfman McInnes Level: advanced 238136851e7fSLois Curfman McInnes 2382b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 2383b4fd4287SBarry Smith @*/ 23847087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 2385b4fd4287SBarry Smith { 23866cab3a1bSJed Brown PetscErrorCode ierr; 23876cab3a1bSJed Brown DM dm; 23886cab3a1bSJed Brown SNESDM sdm; 23896cab3a1bSJed Brown 23903a40ed3dSBarry Smith PetscFunctionBegin; 23910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2392b4fd4287SBarry Smith if (A) *A = snes->jacobian; 2393b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 23946cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 23956cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 23966cab3a1bSJed Brown if (func) *func = sdm->computejacobian; 23976cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 23983a40ed3dSBarry Smith PetscFunctionReturn(0); 2399b4fd4287SBarry Smith } 2400b4fd4287SBarry Smith 24019b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 24029b94acceSBarry Smith 24034a2ae208SSatish Balay #undef __FUNCT__ 24044a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 24059b94acceSBarry Smith /*@ 24069b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2407272ac6f2SLois Curfman McInnes of a nonlinear solver. 24089b94acceSBarry Smith 2409fee21e36SBarry Smith Collective on SNES 2410fee21e36SBarry Smith 2411c7afd0dbSLois Curfman McInnes Input Parameters: 241270e92668SMatthew Knepley . snes - the SNES context 2413c7afd0dbSLois Curfman McInnes 2414272ac6f2SLois Curfman McInnes Notes: 2415272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2416272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2417272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2418272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2419272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2420272ac6f2SLois Curfman McInnes 242136851e7fSLois Curfman McInnes Level: advanced 242236851e7fSLois Curfman McInnes 24239b94acceSBarry Smith .keywords: SNES, nonlinear, setup 24249b94acceSBarry Smith 24259b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 24269b94acceSBarry Smith @*/ 24277087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 24289b94acceSBarry Smith { 2429dfbe8321SBarry Smith PetscErrorCode ierr; 24306cab3a1bSJed Brown DM dm; 24316cab3a1bSJed Brown SNESDM sdm; 2432c35f09e5SBarry Smith SNESLineSearch linesearch, pclinesearch; 24336e2a1849SPeter Brune void *lsprectx,*lspostctx; 24346e2a1849SPeter Brune SNESLineSearchPreCheckFunc lsprefunc; 24356e2a1849SPeter Brune SNESLineSearchPostCheckFunc lspostfunc; 24366e2a1849SPeter Brune PetscErrorCode (*func)(SNES,Vec,Vec,void*); 24376e2a1849SPeter Brune Vec f,fpc; 24386e2a1849SPeter Brune void *funcctx; 24396e2a1849SPeter Brune PetscErrorCode (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 24401eb13d49SPeter Brune void *jacctx,*appctx; 24416e2a1849SPeter Brune Mat A,B; 24423a40ed3dSBarry Smith 24433a40ed3dSBarry Smith PetscFunctionBegin; 24440700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 24454dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 24469b94acceSBarry Smith 24477adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 244885385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 244985385478SLisandro Dalcin } 245085385478SLisandro Dalcin 2451a63bb30eSJed Brown ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 245217186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 245358c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 245458c9b817SLisandro Dalcin 245558c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 245658c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 245758c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 245858c9b817SLisandro Dalcin } 245958c9b817SLisandro Dalcin 24606cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2461d8f46077SPeter Brune ierr = DMShellSetGlobalVector(snes->dm,snes->vec_sol);CHKERRQ(ierr); 24626cab3a1bSJed Brown ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */ 24636cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 24646cab3a1bSJed Brown if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc"); 24656cab3a1bSJed Brown if (!snes->vec_func) { 24666cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2467214df951SJed Brown } 2468efd51863SBarry Smith 2469b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 2470b710008aSBarry Smith 2471f1c6b773SPeter Brune if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);} 24729e764e56SPeter Brune 2473c40d0f55SPeter Brune if (snes->pc && (snes->pcside == PC_LEFT)) snes->mf = PETSC_TRUE; 2474d8f46077SPeter Brune 2475d8f46077SPeter Brune if (snes->mf) { ierr = SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);CHKERRQ(ierr); } 2476d8f46077SPeter Brune 2477d8f46077SPeter Brune 2478d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 2479d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2480d25893d9SBarry Smith } 2481d25893d9SBarry Smith 24826e2a1849SPeter Brune if (snes->pc) { 24836e2a1849SPeter Brune /* copy the DM over */ 24846e2a1849SPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 24856e2a1849SPeter Brune ierr = SNESSetDM(snes->pc,dm);CHKERRQ(ierr); 24866e2a1849SPeter Brune 24876e2a1849SPeter Brune /* copy the legacy SNES context not related to the DM over*/ 24886e2a1849SPeter Brune ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr); 24896e2a1849SPeter Brune ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr); 24906e2a1849SPeter Brune ierr = SNESSetFunction(snes->pc,fpc,func,funcctx);CHKERRQ(ierr); 24916e2a1849SPeter Brune ierr = SNESGetJacobian(snes,&A,&B,&jac,&jacctx);CHKERRQ(ierr); 24926e2a1849SPeter Brune ierr = SNESSetJacobian(snes->pc,A,B,jac,jacctx);CHKERRQ(ierr); 24931eb13d49SPeter Brune ierr = SNESGetApplicationContext(snes,&appctx);CHKERRQ(ierr); 24941eb13d49SPeter Brune ierr = SNESSetApplicationContext(snes->pc,appctx);CHKERRQ(ierr); 24956e2a1849SPeter Brune ierr = VecDestroy(&fpc);CHKERRQ(ierr); 24966e2a1849SPeter Brune 24976e2a1849SPeter Brune /* copy the function pointers over */ 24986e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr); 24996e2a1849SPeter Brune 25006e2a1849SPeter Brune /* default to 1 iteration */ 2501140836e4SPeter Brune ierr = SNESSetTolerances(snes->pc, 0.0, 0.0, 0.0, 1, snes->pc->max_funcs);CHKERRQ(ierr); 25026e2a1849SPeter Brune ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); 25036e2a1849SPeter Brune ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 25046e2a1849SPeter Brune 25056e2a1849SPeter Brune /* copy the line search context over */ 25066e2a1849SPeter Brune ierr = SNESGetSNESLineSearch(snes,&linesearch);CHKERRQ(ierr); 25076e2a1849SPeter Brune ierr = SNESGetSNESLineSearch(snes->pc,&pclinesearch);CHKERRQ(ierr); 25086e2a1849SPeter Brune ierr = SNESLineSearchGetPreCheck(linesearch,&lsprefunc,&lsprectx);CHKERRQ(ierr); 25096e2a1849SPeter Brune ierr = SNESLineSearchGetPostCheck(linesearch,&lspostfunc,&lspostctx);CHKERRQ(ierr); 25106e2a1849SPeter Brune ierr = SNESLineSearchSetPreCheck(pclinesearch,lsprefunc,lsprectx);CHKERRQ(ierr); 25116e2a1849SPeter Brune ierr = SNESLineSearchSetPostCheck(pclinesearch,lspostfunc,lspostctx);CHKERRQ(ierr); 25126e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr); 25136e2a1849SPeter Brune } 25146e2a1849SPeter Brune 2515410397dcSLisandro Dalcin if (snes->ops->setup) { 2516410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2517410397dcSLisandro Dalcin } 251858c9b817SLisandro Dalcin 25197aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 25203a40ed3dSBarry Smith PetscFunctionReturn(0); 25219b94acceSBarry Smith } 25229b94acceSBarry Smith 25234a2ae208SSatish Balay #undef __FUNCT__ 252437596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 252537596af1SLisandro Dalcin /*@ 252637596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 252737596af1SLisandro Dalcin 252837596af1SLisandro Dalcin Collective on SNES 252937596af1SLisandro Dalcin 253037596af1SLisandro Dalcin Input Parameter: 253137596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 253237596af1SLisandro Dalcin 2533d25893d9SBarry Smith Level: intermediate 2534d25893d9SBarry Smith 2535d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 253637596af1SLisandro Dalcin 253737596af1SLisandro Dalcin .keywords: SNES, destroy 253837596af1SLisandro Dalcin 253937596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 254037596af1SLisandro Dalcin @*/ 254137596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 254237596af1SLisandro Dalcin { 254337596af1SLisandro Dalcin PetscErrorCode ierr; 254437596af1SLisandro Dalcin 254537596af1SLisandro Dalcin PetscFunctionBegin; 254637596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2547d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2548d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2549d25893d9SBarry Smith snes->user = PETSC_NULL; 2550d25893d9SBarry Smith } 25518a23116dSBarry Smith if (snes->pc) { 25528a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 25538a23116dSBarry Smith } 25548a23116dSBarry Smith 255537596af1SLisandro Dalcin if (snes->ops->reset) { 255637596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 255737596af1SLisandro Dalcin } 25589e764e56SPeter Brune if (snes->ksp) { 25599e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 25609e764e56SPeter Brune } 25619e764e56SPeter Brune 25629e764e56SPeter Brune if (snes->linesearch) { 2563f1c6b773SPeter Brune ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 25649e764e56SPeter Brune } 25659e764e56SPeter Brune 25666bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 25676bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 25686bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 25696bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 25706bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 25716bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2572c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2573c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 257437596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 257537596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 257637596af1SLisandro Dalcin PetscFunctionReturn(0); 257737596af1SLisandro Dalcin } 257837596af1SLisandro Dalcin 257937596af1SLisandro Dalcin #undef __FUNCT__ 25804a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 258152baeb72SSatish Balay /*@ 25829b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 25839b94acceSBarry Smith with SNESCreate(). 25849b94acceSBarry Smith 2585c7afd0dbSLois Curfman McInnes Collective on SNES 2586c7afd0dbSLois Curfman McInnes 25879b94acceSBarry Smith Input Parameter: 25889b94acceSBarry Smith . snes - the SNES context 25899b94acceSBarry Smith 259036851e7fSLois Curfman McInnes Level: beginner 259136851e7fSLois Curfman McInnes 25929b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 25939b94acceSBarry Smith 259463a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 25959b94acceSBarry Smith @*/ 25966bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 25979b94acceSBarry Smith { 25986849ba73SBarry Smith PetscErrorCode ierr; 25993a40ed3dSBarry Smith 26003a40ed3dSBarry Smith PetscFunctionBegin; 26016bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 26026bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 26036bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2604d4bb536fSBarry Smith 26056bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 26068a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 26076b8b9a38SLisandro Dalcin 2608be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 26096bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 26106bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 26116d4c513bSLisandro Dalcin 26126bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 26136bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 2614f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 26156b8b9a38SLisandro Dalcin 26166bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 26176bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 26186bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 26196b8b9a38SLisandro Dalcin } 26206bf464f9SBarry Smith if ((*snes)->conv_malloc) { 26216bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 26226bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 262358c9b817SLisandro Dalcin } 26246bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2625a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 26263a40ed3dSBarry Smith PetscFunctionReturn(0); 26279b94acceSBarry Smith } 26289b94acceSBarry Smith 26299b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 26309b94acceSBarry Smith 26314a2ae208SSatish Balay #undef __FUNCT__ 2632a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2633a8054027SBarry Smith /*@ 2634a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2635a8054027SBarry Smith 26363f9fe445SBarry Smith Logically Collective on SNES 2637a8054027SBarry Smith 2638a8054027SBarry Smith Input Parameters: 2639a8054027SBarry Smith + snes - the SNES context 2640a8054027SBarry 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 26413b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2642a8054027SBarry Smith 2643a8054027SBarry Smith Options Database Keys: 2644a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2645a8054027SBarry Smith 2646a8054027SBarry Smith Notes: 2647a8054027SBarry Smith The default is 1 2648a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2649a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2650a8054027SBarry Smith 2651a8054027SBarry Smith Level: intermediate 2652a8054027SBarry Smith 2653a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2654a8054027SBarry Smith 2655e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2656a8054027SBarry Smith 2657a8054027SBarry Smith @*/ 26587087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2659a8054027SBarry Smith { 2660a8054027SBarry Smith PetscFunctionBegin; 26610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2662e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2663e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2664c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2665a8054027SBarry Smith snes->lagpreconditioner = lag; 2666a8054027SBarry Smith PetscFunctionReturn(0); 2667a8054027SBarry Smith } 2668a8054027SBarry Smith 2669a8054027SBarry Smith #undef __FUNCT__ 2670efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2671efd51863SBarry Smith /*@ 2672efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2673efd51863SBarry Smith 2674efd51863SBarry Smith Logically Collective on SNES 2675efd51863SBarry Smith 2676efd51863SBarry Smith Input Parameters: 2677efd51863SBarry Smith + snes - the SNES context 2678efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2679efd51863SBarry Smith 2680efd51863SBarry Smith Options Database Keys: 2681efd51863SBarry Smith . -snes_grid_sequence <steps> 2682efd51863SBarry Smith 2683efd51863SBarry Smith Level: intermediate 2684efd51863SBarry Smith 2685c0df2a02SJed Brown Notes: 2686c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2687c0df2a02SJed Brown 2688efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2689efd51863SBarry Smith 2690efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2691efd51863SBarry Smith 2692efd51863SBarry Smith @*/ 2693efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2694efd51863SBarry Smith { 2695efd51863SBarry Smith PetscFunctionBegin; 2696efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2697efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2698efd51863SBarry Smith snes->gridsequence = steps; 2699efd51863SBarry Smith PetscFunctionReturn(0); 2700efd51863SBarry Smith } 2701efd51863SBarry Smith 2702efd51863SBarry Smith #undef __FUNCT__ 2703a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2704a8054027SBarry Smith /*@ 2705a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2706a8054027SBarry Smith 27073f9fe445SBarry Smith Not Collective 2708a8054027SBarry Smith 2709a8054027SBarry Smith Input Parameter: 2710a8054027SBarry Smith . snes - the SNES context 2711a8054027SBarry Smith 2712a8054027SBarry Smith Output Parameter: 2713a8054027SBarry 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 27143b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2715a8054027SBarry Smith 2716a8054027SBarry Smith Options Database Keys: 2717a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2718a8054027SBarry Smith 2719a8054027SBarry Smith Notes: 2720a8054027SBarry Smith The default is 1 2721a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2722a8054027SBarry Smith 2723a8054027SBarry Smith Level: intermediate 2724a8054027SBarry Smith 2725a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2726a8054027SBarry Smith 2727a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2728a8054027SBarry Smith 2729a8054027SBarry Smith @*/ 27307087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2731a8054027SBarry Smith { 2732a8054027SBarry Smith PetscFunctionBegin; 27330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2734a8054027SBarry Smith *lag = snes->lagpreconditioner; 2735a8054027SBarry Smith PetscFunctionReturn(0); 2736a8054027SBarry Smith } 2737a8054027SBarry Smith 2738a8054027SBarry Smith #undef __FUNCT__ 2739e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2740e35cf81dSBarry Smith /*@ 2741e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2742e35cf81dSBarry Smith often the preconditioner is rebuilt. 2743e35cf81dSBarry Smith 27443f9fe445SBarry Smith Logically Collective on SNES 2745e35cf81dSBarry Smith 2746e35cf81dSBarry Smith Input Parameters: 2747e35cf81dSBarry Smith + snes - the SNES context 2748e35cf81dSBarry 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 2749fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2750e35cf81dSBarry Smith 2751e35cf81dSBarry Smith Options Database Keys: 2752e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2753e35cf81dSBarry Smith 2754e35cf81dSBarry Smith Notes: 2755e35cf81dSBarry Smith The default is 1 2756e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2757fe3ffe1eSBarry 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 2758fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2759e35cf81dSBarry Smith 2760e35cf81dSBarry Smith Level: intermediate 2761e35cf81dSBarry Smith 2762e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2763e35cf81dSBarry Smith 2764e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2765e35cf81dSBarry Smith 2766e35cf81dSBarry Smith @*/ 27677087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2768e35cf81dSBarry Smith { 2769e35cf81dSBarry Smith PetscFunctionBegin; 27700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2771e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2772e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2773c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2774e35cf81dSBarry Smith snes->lagjacobian = lag; 2775e35cf81dSBarry Smith PetscFunctionReturn(0); 2776e35cf81dSBarry Smith } 2777e35cf81dSBarry Smith 2778e35cf81dSBarry Smith #undef __FUNCT__ 2779e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2780e35cf81dSBarry Smith /*@ 2781e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2782e35cf81dSBarry Smith 27833f9fe445SBarry Smith Not Collective 2784e35cf81dSBarry Smith 2785e35cf81dSBarry Smith Input Parameter: 2786e35cf81dSBarry Smith . snes - the SNES context 2787e35cf81dSBarry Smith 2788e35cf81dSBarry Smith Output Parameter: 2789e35cf81dSBarry 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 2790e35cf81dSBarry Smith the Jacobian is built etc. 2791e35cf81dSBarry Smith 2792e35cf81dSBarry Smith Options Database Keys: 2793e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2794e35cf81dSBarry Smith 2795e35cf81dSBarry Smith Notes: 2796e35cf81dSBarry Smith The default is 1 2797e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2798e35cf81dSBarry Smith 2799e35cf81dSBarry Smith Level: intermediate 2800e35cf81dSBarry Smith 2801e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2802e35cf81dSBarry Smith 2803e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2804e35cf81dSBarry Smith 2805e35cf81dSBarry Smith @*/ 28067087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2807e35cf81dSBarry Smith { 2808e35cf81dSBarry Smith PetscFunctionBegin; 28090700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2810e35cf81dSBarry Smith *lag = snes->lagjacobian; 2811e35cf81dSBarry Smith PetscFunctionReturn(0); 2812e35cf81dSBarry Smith } 2813e35cf81dSBarry Smith 2814e35cf81dSBarry Smith #undef __FUNCT__ 28154a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 28169b94acceSBarry Smith /*@ 2817d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 28189b94acceSBarry Smith 28193f9fe445SBarry Smith Logically Collective on SNES 2820c7afd0dbSLois Curfman McInnes 28219b94acceSBarry Smith Input Parameters: 2822c7afd0dbSLois Curfman McInnes + snes - the SNES context 282370441072SBarry Smith . abstol - absolute convergence tolerance 282433174efeSLois Curfman McInnes . rtol - relative convergence tolerance 282533174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 282633174efeSLois Curfman McInnes of the change in the solution between steps 282733174efeSLois Curfman McInnes . maxit - maximum number of iterations 2828c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2829fee21e36SBarry Smith 283033174efeSLois Curfman McInnes Options Database Keys: 283170441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2832c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2833c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2834c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2835c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 28369b94acceSBarry Smith 2837d7a720efSLois Curfman McInnes Notes: 28389b94acceSBarry Smith The default maximum number of iterations is 50. 28399b94acceSBarry Smith The default maximum number of function evaluations is 1000. 28409b94acceSBarry Smith 284136851e7fSLois Curfman McInnes Level: intermediate 284236851e7fSLois Curfman McInnes 284333174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 28449b94acceSBarry Smith 28452492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 28469b94acceSBarry Smith @*/ 28477087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 28489b94acceSBarry Smith { 28493a40ed3dSBarry Smith PetscFunctionBegin; 28500700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2851c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2852c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2853c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2854c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2855c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2856c5eb9154SBarry Smith 2857ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2858ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2859ab54825eSJed Brown snes->abstol = abstol; 2860ab54825eSJed Brown } 2861ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2862ab54825eSJed 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); 2863ab54825eSJed Brown snes->rtol = rtol; 2864ab54825eSJed Brown } 2865ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2866ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2867c60f73f4SPeter Brune snes->stol = stol; 2868ab54825eSJed Brown } 2869ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2870ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2871ab54825eSJed Brown snes->max_its = maxit; 2872ab54825eSJed Brown } 2873ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2874ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2875ab54825eSJed Brown snes->max_funcs = maxf; 2876ab54825eSJed Brown } 287788976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 28783a40ed3dSBarry Smith PetscFunctionReturn(0); 28799b94acceSBarry Smith } 28809b94acceSBarry Smith 28814a2ae208SSatish Balay #undef __FUNCT__ 28824a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 28839b94acceSBarry Smith /*@ 288433174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 288533174efeSLois Curfman McInnes 2886c7afd0dbSLois Curfman McInnes Not Collective 2887c7afd0dbSLois Curfman McInnes 288833174efeSLois Curfman McInnes Input Parameters: 2889c7afd0dbSLois Curfman McInnes + snes - the SNES context 289085385478SLisandro Dalcin . atol - absolute convergence tolerance 289133174efeSLois Curfman McInnes . rtol - relative convergence tolerance 289233174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 289333174efeSLois Curfman McInnes of the change in the solution between steps 289433174efeSLois Curfman McInnes . maxit - maximum number of iterations 2895c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2896fee21e36SBarry Smith 289733174efeSLois Curfman McInnes Notes: 289833174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 289933174efeSLois Curfman McInnes 290036851e7fSLois Curfman McInnes Level: intermediate 290136851e7fSLois Curfman McInnes 290233174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 290333174efeSLois Curfman McInnes 290433174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 290533174efeSLois Curfman McInnes @*/ 29067087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 290733174efeSLois Curfman McInnes { 29083a40ed3dSBarry Smith PetscFunctionBegin; 29090700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 291085385478SLisandro Dalcin if (atol) *atol = snes->abstol; 291133174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 2912c60f73f4SPeter Brune if (stol) *stol = snes->stol; 291333174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 291433174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 29153a40ed3dSBarry Smith PetscFunctionReturn(0); 291633174efeSLois Curfman McInnes } 291733174efeSLois Curfman McInnes 29184a2ae208SSatish Balay #undef __FUNCT__ 29194a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 292033174efeSLois Curfman McInnes /*@ 29219b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 29229b94acceSBarry Smith 29233f9fe445SBarry Smith Logically Collective on SNES 2924fee21e36SBarry Smith 2925c7afd0dbSLois Curfman McInnes Input Parameters: 2926c7afd0dbSLois Curfman McInnes + snes - the SNES context 2927c7afd0dbSLois Curfman McInnes - tol - tolerance 2928c7afd0dbSLois Curfman McInnes 29299b94acceSBarry Smith Options Database Key: 2930c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 29319b94acceSBarry Smith 293236851e7fSLois Curfman McInnes Level: intermediate 293336851e7fSLois Curfman McInnes 29349b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 29359b94acceSBarry Smith 29362492ecdbSBarry Smith .seealso: SNESSetTolerances() 29379b94acceSBarry Smith @*/ 29387087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 29399b94acceSBarry Smith { 29403a40ed3dSBarry Smith PetscFunctionBegin; 29410700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2942c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 29439b94acceSBarry Smith snes->deltatol = tol; 29443a40ed3dSBarry Smith PetscFunctionReturn(0); 29459b94acceSBarry Smith } 29469b94acceSBarry Smith 2947df9fa365SBarry Smith /* 2948df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2949df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2950df9fa365SBarry Smith macros instead of functions 2951df9fa365SBarry Smith */ 29524a2ae208SSatish Balay #undef __FUNCT__ 29534619e776SBarry Smith #define __FUNCT__ "SNESMonitorLGResidualNorm" 29544619e776SBarry Smith PetscErrorCode SNESMonitorLGResidualNorm(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2955ce1608b8SBarry Smith { 2956dfbe8321SBarry Smith PetscErrorCode ierr; 2957ce1608b8SBarry Smith 2958ce1608b8SBarry Smith PetscFunctionBegin; 29590700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2960a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2961ce1608b8SBarry Smith PetscFunctionReturn(0); 2962ce1608b8SBarry Smith } 2963ce1608b8SBarry Smith 29644a2ae208SSatish Balay #undef __FUNCT__ 2965a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 29667087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2967df9fa365SBarry Smith { 2968dfbe8321SBarry Smith PetscErrorCode ierr; 2969df9fa365SBarry Smith 2970df9fa365SBarry Smith PetscFunctionBegin; 2971a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2972df9fa365SBarry Smith PetscFunctionReturn(0); 2973df9fa365SBarry Smith } 2974df9fa365SBarry Smith 29754a2ae208SSatish Balay #undef __FUNCT__ 2976a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 29776bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2978df9fa365SBarry Smith { 2979dfbe8321SBarry Smith PetscErrorCode ierr; 2980df9fa365SBarry Smith 2981df9fa365SBarry Smith PetscFunctionBegin; 2982a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2983df9fa365SBarry Smith PetscFunctionReturn(0); 2984df9fa365SBarry Smith } 2985df9fa365SBarry Smith 29867087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2987b271bb04SBarry Smith #undef __FUNCT__ 2988b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 29897087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2990b271bb04SBarry Smith { 2991b271bb04SBarry Smith PetscDrawLG lg; 2992b271bb04SBarry Smith PetscErrorCode ierr; 2993b271bb04SBarry Smith PetscReal x,y,per; 2994b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2995b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2996b271bb04SBarry Smith PetscDraw draw; 2997b271bb04SBarry Smith 2998*459f5d12SBarry Smith PetscFunctionBegin; 2999b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 3000b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3001b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3002b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 3003b271bb04SBarry Smith x = (PetscReal) n; 3004b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 3005b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3006b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 3007b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 3008b271bb04SBarry Smith } 3009b271bb04SBarry Smith 3010b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 3011b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3012b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3013b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 3014b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 3015b271bb04SBarry Smith x = (PetscReal) n; 3016b271bb04SBarry Smith y = 100.0*per; 3017b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3018b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 3019b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 3020b271bb04SBarry Smith } 3021b271bb04SBarry Smith 3022b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 3023b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3024b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3025b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 3026b271bb04SBarry Smith x = (PetscReal) n; 3027b271bb04SBarry Smith y = (prev - rnorm)/prev; 3028b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3029b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 3030b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 3031b271bb04SBarry Smith } 3032b271bb04SBarry Smith 3033b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 3034b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3035b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3036b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 3037b271bb04SBarry Smith x = (PetscReal) n; 3038b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 3039b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 3040b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3041b271bb04SBarry Smith } 3042b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 3043b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 3044b271bb04SBarry Smith } 3045b271bb04SBarry Smith prev = rnorm; 3046b271bb04SBarry Smith PetscFunctionReturn(0); 3047b271bb04SBarry Smith } 3048b271bb04SBarry Smith 3049b271bb04SBarry Smith #undef __FUNCT__ 30507a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 3051228d79bcSJed Brown /*@ 3052228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 3053228d79bcSJed Brown 3054228d79bcSJed Brown Collective on SNES 3055228d79bcSJed Brown 3056228d79bcSJed Brown Input Parameters: 3057228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 3058228d79bcSJed Brown . iter - iteration number 3059228d79bcSJed Brown - rnorm - relative norm of the residual 3060228d79bcSJed Brown 3061228d79bcSJed Brown Notes: 3062228d79bcSJed Brown This routine is called by the SNES implementations. 3063228d79bcSJed Brown It does not typically need to be called by the user. 3064228d79bcSJed Brown 3065228d79bcSJed Brown Level: developer 3066228d79bcSJed Brown 3067228d79bcSJed Brown .seealso: SNESMonitorSet() 3068228d79bcSJed Brown @*/ 30697a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 30707a03ce2fSLisandro Dalcin { 30717a03ce2fSLisandro Dalcin PetscErrorCode ierr; 30727a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 30737a03ce2fSLisandro Dalcin 30747a03ce2fSLisandro Dalcin PetscFunctionBegin; 30757a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 30767a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 30777a03ce2fSLisandro Dalcin } 30787a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 30797a03ce2fSLisandro Dalcin } 30807a03ce2fSLisandro Dalcin 30819b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 30829b94acceSBarry Smith 30834a2ae208SSatish Balay #undef __FUNCT__ 3084a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 30859b94acceSBarry Smith /*@C 3086a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 30879b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 30889b94acceSBarry Smith progress. 30899b94acceSBarry Smith 30903f9fe445SBarry Smith Logically Collective on SNES 3091fee21e36SBarry Smith 3092c7afd0dbSLois Curfman McInnes Input Parameters: 3093c7afd0dbSLois Curfman McInnes + snes - the SNES context 3094c7afd0dbSLois Curfman McInnes . func - monitoring routine 3095b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 3096e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 3097b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 3098b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 30999b94acceSBarry Smith 3100c7afd0dbSLois Curfman McInnes Calling sequence of func: 3101a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 3102c7afd0dbSLois Curfman McInnes 3103c7afd0dbSLois Curfman McInnes + snes - the SNES context 3104c7afd0dbSLois Curfman McInnes . its - iteration number 3105c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 310640a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 31079b94acceSBarry Smith 31089665c990SLois Curfman McInnes Options Database Keys: 3109a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 31104619e776SBarry Smith . -snes_monitor_lg_residualnorm - sets line graph monitor, 3111a6570f20SBarry Smith uses SNESMonitorLGCreate() 3112cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 3113c7afd0dbSLois Curfman McInnes been hardwired into a code by 3114a6570f20SBarry Smith calls to SNESMonitorSet(), but 3115c7afd0dbSLois Curfman McInnes does not cancel those set via 3116c7afd0dbSLois Curfman McInnes the options database. 31179665c990SLois Curfman McInnes 3118639f9d9dSBarry Smith Notes: 31196bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 3120a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 31216bc08f3fSLois Curfman McInnes order in which they were set. 3122639f9d9dSBarry Smith 3123025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 3124025f1a04SBarry Smith 312536851e7fSLois Curfman McInnes Level: intermediate 312636851e7fSLois Curfman McInnes 31279b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 31289b94acceSBarry Smith 3129a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 31309b94acceSBarry Smith @*/ 3131c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 31329b94acceSBarry Smith { 3133b90d0a6eSBarry Smith PetscInt i; 3134649052a6SBarry Smith PetscErrorCode ierr; 3135b90d0a6eSBarry Smith 31363a40ed3dSBarry Smith PetscFunctionBegin; 31370700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 313817186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 3139b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 3140649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 3141649052a6SBarry Smith if (monitordestroy) { 3142c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 3143649052a6SBarry Smith } 3144b90d0a6eSBarry Smith PetscFunctionReturn(0); 3145b90d0a6eSBarry Smith } 3146b90d0a6eSBarry Smith } 3147b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 3148b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 3149639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 31503a40ed3dSBarry Smith PetscFunctionReturn(0); 31519b94acceSBarry Smith } 31529b94acceSBarry Smith 31534a2ae208SSatish Balay #undef __FUNCT__ 3154a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 31555cd90555SBarry Smith /*@C 3156a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 31575cd90555SBarry Smith 31583f9fe445SBarry Smith Logically Collective on SNES 3159c7afd0dbSLois Curfman McInnes 31605cd90555SBarry Smith Input Parameters: 31615cd90555SBarry Smith . snes - the SNES context 31625cd90555SBarry Smith 31631a480d89SAdministrator Options Database Key: 3164a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 3165a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 3166c7afd0dbSLois Curfman McInnes set via the options database 31675cd90555SBarry Smith 31685cd90555SBarry Smith Notes: 31695cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 31705cd90555SBarry Smith 317136851e7fSLois Curfman McInnes Level: intermediate 317236851e7fSLois Curfman McInnes 31735cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 31745cd90555SBarry Smith 3175a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 31765cd90555SBarry Smith @*/ 31777087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 31785cd90555SBarry Smith { 3179d952e501SBarry Smith PetscErrorCode ierr; 3180d952e501SBarry Smith PetscInt i; 3181d952e501SBarry Smith 31825cd90555SBarry Smith PetscFunctionBegin; 31830700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3184d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 3185d952e501SBarry Smith if (snes->monitordestroy[i]) { 31863c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 3187d952e501SBarry Smith } 3188d952e501SBarry Smith } 31895cd90555SBarry Smith snes->numbermonitors = 0; 31905cd90555SBarry Smith PetscFunctionReturn(0); 31915cd90555SBarry Smith } 31925cd90555SBarry Smith 31934a2ae208SSatish Balay #undef __FUNCT__ 31944a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 31959b94acceSBarry Smith /*@C 31969b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 31979b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 31989b94acceSBarry Smith 31993f9fe445SBarry Smith Logically Collective on SNES 3200fee21e36SBarry Smith 3201c7afd0dbSLois Curfman McInnes Input Parameters: 3202c7afd0dbSLois Curfman McInnes + snes - the SNES context 3203c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 32047f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 32057f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 32069b94acceSBarry Smith 3207c7afd0dbSLois Curfman McInnes Calling sequence of func: 320806ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 3209c7afd0dbSLois Curfman McInnes 3210c7afd0dbSLois Curfman McInnes + snes - the SNES context 321106ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 3212c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 3213184914b5SBarry Smith . reason - reason for convergence/divergence 3214c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 32154b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 32164b27c08aSLois Curfman McInnes - f - 2-norm of function 32179b94acceSBarry Smith 321836851e7fSLois Curfman McInnes Level: advanced 321936851e7fSLois Curfman McInnes 32209b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 32219b94acceSBarry Smith 322285385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 32239b94acceSBarry Smith @*/ 32247087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 32259b94acceSBarry Smith { 32267f7931b9SBarry Smith PetscErrorCode ierr; 32277f7931b9SBarry Smith 32283a40ed3dSBarry Smith PetscFunctionBegin; 32290700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 323085385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 32317f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 32327f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 32337f7931b9SBarry Smith } 323485385478SLisandro Dalcin snes->ops->converged = func; 32357f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 323685385478SLisandro Dalcin snes->cnvP = cctx; 32373a40ed3dSBarry Smith PetscFunctionReturn(0); 32389b94acceSBarry Smith } 32399b94acceSBarry Smith 32404a2ae208SSatish Balay #undef __FUNCT__ 32414a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 324252baeb72SSatish Balay /*@ 3243184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 3244184914b5SBarry Smith 3245184914b5SBarry Smith Not Collective 3246184914b5SBarry Smith 3247184914b5SBarry Smith Input Parameter: 3248184914b5SBarry Smith . snes - the SNES context 3249184914b5SBarry Smith 3250184914b5SBarry Smith Output Parameter: 32514d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 3252184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 3253184914b5SBarry Smith 3254184914b5SBarry Smith Level: intermediate 3255184914b5SBarry Smith 3256184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 3257184914b5SBarry Smith 3258184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 3259184914b5SBarry Smith 326085385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 3261184914b5SBarry Smith @*/ 32627087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 3263184914b5SBarry Smith { 3264184914b5SBarry Smith PetscFunctionBegin; 32650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 32664482741eSBarry Smith PetscValidPointer(reason,2); 3267184914b5SBarry Smith *reason = snes->reason; 3268184914b5SBarry Smith PetscFunctionReturn(0); 3269184914b5SBarry Smith } 3270184914b5SBarry Smith 32714a2ae208SSatish Balay #undef __FUNCT__ 32724a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 3273c9005455SLois Curfman McInnes /*@ 3274c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 3275c9005455SLois Curfman McInnes 32763f9fe445SBarry Smith Logically Collective on SNES 3277fee21e36SBarry Smith 3278c7afd0dbSLois Curfman McInnes Input Parameters: 3279c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 32808c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 3281cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 3282758f92a0SBarry Smith . na - size of a and its 328364731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 3284758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 3285c7afd0dbSLois Curfman McInnes 3286308dcc3eSBarry Smith Notes: 3287308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 3288308dcc3eSBarry Smith default array of length 10000 is allocated. 3289308dcc3eSBarry Smith 3290c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 3291c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 3292c9005455SLois Curfman McInnes during the section of code that is being timed. 3293c9005455SLois Curfman McInnes 329436851e7fSLois Curfman McInnes Level: intermediate 329536851e7fSLois Curfman McInnes 3296c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 3297758f92a0SBarry Smith 329808405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 3299758f92a0SBarry Smith 3300c9005455SLois Curfman McInnes @*/ 33017087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 3302c9005455SLois Curfman McInnes { 3303308dcc3eSBarry Smith PetscErrorCode ierr; 3304308dcc3eSBarry Smith 33053a40ed3dSBarry Smith PetscFunctionBegin; 33060700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 33074482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 3308a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 3309308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 3310308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 3311308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 3312308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 3313308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 3314308dcc3eSBarry Smith } 3315c9005455SLois Curfman McInnes snes->conv_hist = a; 3316758f92a0SBarry Smith snes->conv_hist_its = its; 3317758f92a0SBarry Smith snes->conv_hist_max = na; 3318a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 3319758f92a0SBarry Smith snes->conv_hist_reset = reset; 3320758f92a0SBarry Smith PetscFunctionReturn(0); 3321758f92a0SBarry Smith } 3322758f92a0SBarry Smith 3323308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3324c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 3325c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 3326308dcc3eSBarry Smith EXTERN_C_BEGIN 3327308dcc3eSBarry Smith #undef __FUNCT__ 3328308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 3329308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3330308dcc3eSBarry Smith { 3331308dcc3eSBarry Smith mxArray *mat; 3332308dcc3eSBarry Smith PetscInt i; 3333308dcc3eSBarry Smith PetscReal *ar; 3334308dcc3eSBarry Smith 3335308dcc3eSBarry Smith PetscFunctionBegin; 3336308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3337308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3338308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 3339308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 3340308dcc3eSBarry Smith } 3341308dcc3eSBarry Smith PetscFunctionReturn(mat); 3342308dcc3eSBarry Smith } 3343308dcc3eSBarry Smith EXTERN_C_END 3344308dcc3eSBarry Smith #endif 3345308dcc3eSBarry Smith 3346308dcc3eSBarry Smith 33474a2ae208SSatish Balay #undef __FUNCT__ 33484a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 33490c4c9dddSBarry Smith /*@C 3350758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3351758f92a0SBarry Smith 33523f9fe445SBarry Smith Not Collective 3353758f92a0SBarry Smith 3354758f92a0SBarry Smith Input Parameter: 3355758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3356758f92a0SBarry Smith 3357758f92a0SBarry Smith Output Parameters: 3358758f92a0SBarry Smith . a - array to hold history 3359758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3360758f92a0SBarry Smith negative if not converged) for each solve. 3361758f92a0SBarry Smith - na - size of a and its 3362758f92a0SBarry Smith 3363758f92a0SBarry Smith Notes: 3364758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3365758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3366758f92a0SBarry Smith 3367758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3368758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3369758f92a0SBarry Smith during the section of code that is being timed. 3370758f92a0SBarry Smith 3371758f92a0SBarry Smith Level: intermediate 3372758f92a0SBarry Smith 3373758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3374758f92a0SBarry Smith 3375758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3376758f92a0SBarry Smith 3377758f92a0SBarry Smith @*/ 33787087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3379758f92a0SBarry Smith { 3380758f92a0SBarry Smith PetscFunctionBegin; 33810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3382758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3383758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3384758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 33853a40ed3dSBarry Smith PetscFunctionReturn(0); 3386c9005455SLois Curfman McInnes } 3387c9005455SLois Curfman McInnes 3388e74ef692SMatthew Knepley #undef __FUNCT__ 3389e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 3390ac226902SBarry Smith /*@C 339176b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3392eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 33937e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 339476b2cf59SMatthew Knepley 33953f9fe445SBarry Smith Logically Collective on SNES 339676b2cf59SMatthew Knepley 339776b2cf59SMatthew Knepley Input Parameters: 339876b2cf59SMatthew Knepley . snes - The nonlinear solver context 339976b2cf59SMatthew Knepley . func - The function 340076b2cf59SMatthew Knepley 340176b2cf59SMatthew Knepley Calling sequence of func: 3402b5d30489SBarry Smith . func (SNES snes, PetscInt step); 340376b2cf59SMatthew Knepley 340476b2cf59SMatthew Knepley . step - The current step of the iteration 340576b2cf59SMatthew Knepley 3406fe97e370SBarry Smith Level: advanced 3407fe97e370SBarry Smith 3408fe97e370SBarry 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() 3409fe97e370SBarry Smith This is not used by most users. 341076b2cf59SMatthew Knepley 341176b2cf59SMatthew Knepley .keywords: SNES, update 3412b5d30489SBarry Smith 341385385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 341476b2cf59SMatthew Knepley @*/ 34157087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 341676b2cf59SMatthew Knepley { 341776b2cf59SMatthew Knepley PetscFunctionBegin; 34180700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3419e7788613SBarry Smith snes->ops->update = func; 342076b2cf59SMatthew Knepley PetscFunctionReturn(0); 342176b2cf59SMatthew Knepley } 342276b2cf59SMatthew Knepley 3423e74ef692SMatthew Knepley #undef __FUNCT__ 3424e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 342576b2cf59SMatthew Knepley /*@ 342676b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 342776b2cf59SMatthew Knepley 342876b2cf59SMatthew Knepley Not collective 342976b2cf59SMatthew Knepley 343076b2cf59SMatthew Knepley Input Parameters: 343176b2cf59SMatthew Knepley . snes - The nonlinear solver context 343276b2cf59SMatthew Knepley . step - The current step of the iteration 343376b2cf59SMatthew Knepley 3434205452f4SMatthew Knepley Level: intermediate 3435205452f4SMatthew Knepley 343676b2cf59SMatthew Knepley .keywords: SNES, update 3437a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 343876b2cf59SMatthew Knepley @*/ 34397087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 344076b2cf59SMatthew Knepley { 344176b2cf59SMatthew Knepley PetscFunctionBegin; 344276b2cf59SMatthew Knepley PetscFunctionReturn(0); 344376b2cf59SMatthew Knepley } 344476b2cf59SMatthew Knepley 34454a2ae208SSatish Balay #undef __FUNCT__ 34464a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 34479b94acceSBarry Smith /* 34489b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 34499b94acceSBarry Smith positive parameter delta. 34509b94acceSBarry Smith 34519b94acceSBarry Smith Input Parameters: 3452c7afd0dbSLois Curfman McInnes + snes - the SNES context 34539b94acceSBarry Smith . y - approximate solution of linear system 34549b94acceSBarry Smith . fnorm - 2-norm of current function 3455c7afd0dbSLois Curfman McInnes - delta - trust region size 34569b94acceSBarry Smith 34579b94acceSBarry Smith Output Parameters: 3458c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 34599b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 34609b94acceSBarry Smith region, and exceeds zero otherwise. 3461c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 34629b94acceSBarry Smith 34639b94acceSBarry Smith Note: 34644b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 34659b94acceSBarry Smith is set to be the maximum allowable step size. 34669b94acceSBarry Smith 34679b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 34689b94acceSBarry Smith */ 3469dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 34709b94acceSBarry Smith { 3471064f8208SBarry Smith PetscReal nrm; 3472ea709b57SSatish Balay PetscScalar cnorm; 3473dfbe8321SBarry Smith PetscErrorCode ierr; 34743a40ed3dSBarry Smith 34753a40ed3dSBarry Smith PetscFunctionBegin; 34760700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34770700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3478c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3479184914b5SBarry Smith 3480064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3481064f8208SBarry Smith if (nrm > *delta) { 3482064f8208SBarry Smith nrm = *delta/nrm; 3483064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3484064f8208SBarry Smith cnorm = nrm; 34852dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 34869b94acceSBarry Smith *ynorm = *delta; 34879b94acceSBarry Smith } else { 34889b94acceSBarry Smith *gpnorm = 0.0; 3489064f8208SBarry Smith *ynorm = nrm; 34909b94acceSBarry Smith } 34913a40ed3dSBarry Smith PetscFunctionReturn(0); 34929b94acceSBarry Smith } 34939b94acceSBarry Smith 34944a2ae208SSatish Balay #undef __FUNCT__ 34954a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 34966ce558aeSBarry Smith /*@C 3497f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3498f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 34999b94acceSBarry Smith 3500c7afd0dbSLois Curfman McInnes Collective on SNES 3501c7afd0dbSLois Curfman McInnes 3502b2002411SLois Curfman McInnes Input Parameters: 3503c7afd0dbSLois Curfman McInnes + snes - the SNES context 35043cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 350585385478SLisandro Dalcin - x - the solution vector. 35069b94acceSBarry Smith 3507b2002411SLois Curfman McInnes Notes: 35088ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 35098ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 35108ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 35118ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 35128ddd3da0SLois Curfman McInnes 351336851e7fSLois Curfman McInnes Level: beginner 351436851e7fSLois Curfman McInnes 35159b94acceSBarry Smith .keywords: SNES, nonlinear, solve 35169b94acceSBarry Smith 3517c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 35189b94acceSBarry Smith @*/ 35197087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 35209b94acceSBarry Smith { 3521dfbe8321SBarry Smith PetscErrorCode ierr; 3522ace3abfcSBarry Smith PetscBool flg; 3523eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 3524eabae89aSBarry Smith PetscViewer viewer; 3525efd51863SBarry Smith PetscInt grid; 3526a69afd8bSBarry Smith Vec xcreated = PETSC_NULL; 3527caa4e7f2SJed Brown DM dm; 3528052efed2SBarry Smith 35293a40ed3dSBarry Smith PetscFunctionBegin; 35300700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3531a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3532a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 35330700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 353485385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 353585385478SLisandro Dalcin 3536caa4e7f2SJed Brown if (!x) { 3537caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3538caa4e7f2SJed Brown ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 3539a69afd8bSBarry Smith x = xcreated; 3540a69afd8bSBarry Smith } 3541a69afd8bSBarry Smith 3542a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3543efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3544efd51863SBarry Smith 354585385478SLisandro Dalcin /* set solution vector */ 3546efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 35476bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 354885385478SLisandro Dalcin snes->vec_sol = x; 3549caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3550caa4e7f2SJed Brown 3551caa4e7f2SJed Brown /* set affine vector if provided */ 355285385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 35536bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 355485385478SLisandro Dalcin snes->vec_rhs = b; 355585385478SLisandro Dalcin 355670e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 35573f149594SLisandro Dalcin 35587eee914bSBarry Smith if (!grid) { 35597eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3560d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3561dd568438SSatish Balay } else if (snes->dm) { 3562dd568438SSatish Balay PetscBool ig; 3563dd568438SSatish Balay ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr); 3564dd568438SSatish Balay if (ig) { 35657eee914bSBarry Smith ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr); 35667eee914bSBarry Smith } 3567d25893d9SBarry Smith } 3568dd568438SSatish Balay } 3569d25893d9SBarry Smith 3570abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 357150ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3572d5e45103SBarry Smith 35733f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 35744936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 357585385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 35764936397dSBarry Smith if (snes->domainerror){ 35774936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 35784936397dSBarry Smith snes->domainerror = PETSC_FALSE; 35794936397dSBarry Smith } 358017186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 35813f149594SLisandro Dalcin 358290d69ab7SBarry Smith flg = PETSC_FALSE; 3583acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3584da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 35855968eb51SBarry Smith if (snes->printreason) { 3586a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 35875968eb51SBarry Smith if (snes->reason > 0) { 3588c7e7b494SJed 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); 35895968eb51SBarry Smith } else { 3590c7e7b494SJed 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); 35915968eb51SBarry Smith } 3592a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 35935968eb51SBarry Smith } 35945968eb51SBarry Smith 3595e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3596efd51863SBarry Smith if (grid < snes->gridsequence) { 3597efd51863SBarry Smith DM fine; 3598efd51863SBarry Smith Vec xnew; 3599efd51863SBarry Smith Mat interp; 3600efd51863SBarry Smith 3601efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3602c5c77316SJed Brown if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 3603e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3604efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3605efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3606c833c3b5SJed Brown ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr); 3607efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3608efd51863SBarry Smith x = xnew; 3609efd51863SBarry Smith 3610efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3611efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3612efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3613a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3614efd51863SBarry Smith } 3615efd51863SBarry Smith } 36163f7e2da0SPeter Brune /* monitoring and viewing */ 36173f7e2da0SPeter Brune flg = PETSC_FALSE; 36183f7e2da0SPeter Brune ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 36193f7e2da0SPeter Brune if (flg && !PetscPreLoadingOn) { 36203f7e2da0SPeter Brune ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 36213f7e2da0SPeter Brune ierr = SNESView(snes,viewer);CHKERRQ(ierr); 36223f7e2da0SPeter Brune ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 36233f7e2da0SPeter Brune } 36243f7e2da0SPeter Brune 36253f7e2da0SPeter Brune flg = PETSC_FALSE; 36263f7e2da0SPeter Brune ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 36273f7e2da0SPeter Brune if (flg) { 36283f7e2da0SPeter Brune PetscViewer viewer; 36293f7e2da0SPeter Brune ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 36303f7e2da0SPeter Brune ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 36313f7e2da0SPeter Brune ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 36323f7e2da0SPeter Brune ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 36333f7e2da0SPeter Brune ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 36343f7e2da0SPeter Brune } 36353f7e2da0SPeter Brune 3636a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 36373a40ed3dSBarry Smith PetscFunctionReturn(0); 36389b94acceSBarry Smith } 36399b94acceSBarry Smith 36409b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 36419b94acceSBarry Smith 36424a2ae208SSatish Balay #undef __FUNCT__ 36434a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 364482bf6240SBarry Smith /*@C 36454b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 36469b94acceSBarry Smith 3647fee21e36SBarry Smith Collective on SNES 3648fee21e36SBarry Smith 3649c7afd0dbSLois Curfman McInnes Input Parameters: 3650c7afd0dbSLois Curfman McInnes + snes - the SNES context 3651454a90a3SBarry Smith - type - a known method 3652c7afd0dbSLois Curfman McInnes 3653c7afd0dbSLois Curfman McInnes Options Database Key: 3654454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3655c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3656ae12b187SLois Curfman McInnes 36579b94acceSBarry Smith Notes: 3658e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 36594b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3660c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 36614b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3662c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 36639b94acceSBarry Smith 3664ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3665ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3666ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3667ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3668ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3669ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3670ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3671ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3672ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3673b0a32e0cSBarry Smith appropriate method. 367436851e7fSLois Curfman McInnes 367536851e7fSLois Curfman McInnes Level: intermediate 3676a703fe33SLois Curfman McInnes 3677454a90a3SBarry Smith .keywords: SNES, set, type 3678435da068SBarry Smith 3679435da068SBarry Smith .seealso: SNESType, SNESCreate() 3680435da068SBarry Smith 36819b94acceSBarry Smith @*/ 368219fd82e9SBarry Smith PetscErrorCode SNESSetType(SNES snes,SNESType type) 36839b94acceSBarry Smith { 3684dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3685ace3abfcSBarry Smith PetscBool match; 36863a40ed3dSBarry Smith 36873a40ed3dSBarry Smith PetscFunctionBegin; 36880700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36894482741eSBarry Smith PetscValidCharPointer(type,2); 369082bf6240SBarry Smith 3691251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 36920f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 369392ff6ae8SBarry Smith 36944b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3695e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 369675396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 3697b5c23020SJed Brown if (snes->ops->destroy) { 3698b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 3699b5c23020SJed Brown snes->ops->destroy = PETSC_NULL; 3700b5c23020SJed Brown } 370175396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 370275396ef9SLisandro Dalcin snes->ops->setup = 0; 370375396ef9SLisandro Dalcin snes->ops->solve = 0; 370475396ef9SLisandro Dalcin snes->ops->view = 0; 370575396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 370675396ef9SLisandro Dalcin snes->ops->destroy = 0; 370775396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 370875396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3709454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 371003bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 37119fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 37129fb22e1aSBarry Smith if (PetscAMSPublishAll) { 37139fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 37149fb22e1aSBarry Smith } 37159fb22e1aSBarry Smith #endif 37163a40ed3dSBarry Smith PetscFunctionReturn(0); 37179b94acceSBarry Smith } 37189b94acceSBarry Smith 3719a847f771SSatish Balay 37209b94acceSBarry Smith /* --------------------------------------------------------------------- */ 37214a2ae208SSatish Balay #undef __FUNCT__ 37224a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 372352baeb72SSatish Balay /*@ 37249b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3725f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 37269b94acceSBarry Smith 3727fee21e36SBarry Smith Not Collective 3728fee21e36SBarry Smith 372936851e7fSLois Curfman McInnes Level: advanced 373036851e7fSLois Curfman McInnes 37319b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 37329b94acceSBarry Smith 37339b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 37349b94acceSBarry Smith @*/ 37357087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 37369b94acceSBarry Smith { 3737dfbe8321SBarry Smith PetscErrorCode ierr; 373882bf6240SBarry Smith 37393a40ed3dSBarry Smith PetscFunctionBegin; 37401441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 37414c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 37423a40ed3dSBarry Smith PetscFunctionReturn(0); 37439b94acceSBarry Smith } 37449b94acceSBarry Smith 37454a2ae208SSatish Balay #undef __FUNCT__ 37464a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 37479b94acceSBarry Smith /*@C 37489a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 37499b94acceSBarry Smith 3750c7afd0dbSLois Curfman McInnes Not Collective 3751c7afd0dbSLois Curfman McInnes 37529b94acceSBarry Smith Input Parameter: 37534b0e389bSBarry Smith . snes - nonlinear solver context 37549b94acceSBarry Smith 37559b94acceSBarry Smith Output Parameter: 37563a7fca6bSBarry Smith . type - SNES method (a character string) 37579b94acceSBarry Smith 375836851e7fSLois Curfman McInnes Level: intermediate 375936851e7fSLois Curfman McInnes 3760454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 37619b94acceSBarry Smith @*/ 376219fd82e9SBarry Smith PetscErrorCode SNESGetType(SNES snes,SNESType *type) 37639b94acceSBarry Smith { 37643a40ed3dSBarry Smith PetscFunctionBegin; 37650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37664482741eSBarry Smith PetscValidPointer(type,2); 37677adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 37683a40ed3dSBarry Smith PetscFunctionReturn(0); 37699b94acceSBarry Smith } 37709b94acceSBarry Smith 37714a2ae208SSatish Balay #undef __FUNCT__ 37724a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 377352baeb72SSatish Balay /*@ 37749b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3775c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 37769b94acceSBarry Smith 3777c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3778c7afd0dbSLois Curfman McInnes 37799b94acceSBarry Smith Input Parameter: 37809b94acceSBarry Smith . snes - the SNES context 37819b94acceSBarry Smith 37829b94acceSBarry Smith Output Parameter: 37839b94acceSBarry Smith . x - the solution 37849b94acceSBarry Smith 378570e92668SMatthew Knepley Level: intermediate 378636851e7fSLois Curfman McInnes 37879b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 37889b94acceSBarry Smith 378985385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 37909b94acceSBarry Smith @*/ 37917087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 37929b94acceSBarry Smith { 37933a40ed3dSBarry Smith PetscFunctionBegin; 37940700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37954482741eSBarry Smith PetscValidPointer(x,2); 379685385478SLisandro Dalcin *x = snes->vec_sol; 379770e92668SMatthew Knepley PetscFunctionReturn(0); 379870e92668SMatthew Knepley } 379970e92668SMatthew Knepley 380070e92668SMatthew Knepley #undef __FUNCT__ 38014a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 380252baeb72SSatish Balay /*@ 38039b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 38049b94acceSBarry Smith stored. 38059b94acceSBarry Smith 3806c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3807c7afd0dbSLois Curfman McInnes 38089b94acceSBarry Smith Input Parameter: 38099b94acceSBarry Smith . snes - the SNES context 38109b94acceSBarry Smith 38119b94acceSBarry Smith Output Parameter: 38129b94acceSBarry Smith . x - the solution update 38139b94acceSBarry Smith 381436851e7fSLois Curfman McInnes Level: advanced 381536851e7fSLois Curfman McInnes 38169b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 38179b94acceSBarry Smith 381885385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 38199b94acceSBarry Smith @*/ 38207087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 38219b94acceSBarry Smith { 38223a40ed3dSBarry Smith PetscFunctionBegin; 38230700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 38244482741eSBarry Smith PetscValidPointer(x,2); 382585385478SLisandro Dalcin *x = snes->vec_sol_update; 38263a40ed3dSBarry Smith PetscFunctionReturn(0); 38279b94acceSBarry Smith } 38289b94acceSBarry Smith 38294a2ae208SSatish Balay #undef __FUNCT__ 38304a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 38319b94acceSBarry Smith /*@C 38323638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 38339b94acceSBarry Smith 3834a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 3835c7afd0dbSLois Curfman McInnes 38369b94acceSBarry Smith Input Parameter: 38379b94acceSBarry Smith . snes - the SNES context 38389b94acceSBarry Smith 38399b94acceSBarry Smith Output Parameter: 38407bf4e008SBarry Smith + r - the function (or PETSC_NULL) 384170e92668SMatthew Knepley . func - the function (or PETSC_NULL) 384270e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 38439b94acceSBarry Smith 384436851e7fSLois Curfman McInnes Level: advanced 384536851e7fSLois Curfman McInnes 3846a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 38479b94acceSBarry Smith 38484b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 38499b94acceSBarry Smith @*/ 38507087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 38519b94acceSBarry Smith { 3852a63bb30eSJed Brown PetscErrorCode ierr; 38536cab3a1bSJed Brown DM dm; 3854a63bb30eSJed Brown 38553a40ed3dSBarry Smith PetscFunctionBegin; 38560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3857a63bb30eSJed Brown if (r) { 3858a63bb30eSJed Brown if (!snes->vec_func) { 3859a63bb30eSJed Brown if (snes->vec_rhs) { 3860a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 3861a63bb30eSJed Brown } else if (snes->vec_sol) { 3862a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 3863a63bb30eSJed Brown } else if (snes->dm) { 3864a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 3865a63bb30eSJed Brown } 3866a63bb30eSJed Brown } 3867a63bb30eSJed Brown *r = snes->vec_func; 3868a63bb30eSJed Brown } 38696cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 38706cab3a1bSJed Brown ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr); 38713a40ed3dSBarry Smith PetscFunctionReturn(0); 38729b94acceSBarry Smith } 38739b94acceSBarry Smith 3874c79ef259SPeter Brune /*@C 3875c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3876c79ef259SPeter Brune 3877c79ef259SPeter Brune Input Parameter: 3878c79ef259SPeter Brune . snes - the SNES context 3879c79ef259SPeter Brune 3880c79ef259SPeter Brune Output Parameter: 3881c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3882c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3883c79ef259SPeter Brune 3884c79ef259SPeter Brune Level: advanced 3885c79ef259SPeter Brune 3886c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3887c79ef259SPeter Brune 3888c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3889c79ef259SPeter Brune @*/ 3890c79ef259SPeter Brune 38914a2ae208SSatish Balay #undef __FUNCT__ 3892646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3893646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3894646217ecSPeter Brune { 38956cab3a1bSJed Brown PetscErrorCode ierr; 38966cab3a1bSJed Brown DM dm; 38976cab3a1bSJed Brown 3898646217ecSPeter Brune PetscFunctionBegin; 3899646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 39006cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 39016cab3a1bSJed Brown ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr); 3902646217ecSPeter Brune PetscFunctionReturn(0); 3903646217ecSPeter Brune } 3904646217ecSPeter Brune 39054a2ae208SSatish Balay #undef __FUNCT__ 39064a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 39073c7409f5SSatish Balay /*@C 39083c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3909d850072dSLois Curfman McInnes SNES options in the database. 39103c7409f5SSatish Balay 39113f9fe445SBarry Smith Logically Collective on SNES 3912fee21e36SBarry Smith 3913c7afd0dbSLois Curfman McInnes Input Parameter: 3914c7afd0dbSLois Curfman McInnes + snes - the SNES context 3915c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3916c7afd0dbSLois Curfman McInnes 3917d850072dSLois Curfman McInnes Notes: 3918a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3919c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3920d850072dSLois Curfman McInnes 392136851e7fSLois Curfman McInnes Level: advanced 392236851e7fSLois Curfman McInnes 39233c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3924a86d99e1SLois Curfman McInnes 3925a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 39263c7409f5SSatish Balay @*/ 39277087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 39283c7409f5SSatish Balay { 3929dfbe8321SBarry Smith PetscErrorCode ierr; 39303c7409f5SSatish Balay 39313a40ed3dSBarry Smith PetscFunctionBegin; 39320700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3933639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 39341cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 393535f5d045SPeter Brune if (snes->linesearch) { 393635f5d045SPeter Brune ierr = SNESGetSNESLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 393708b6c495SPeter Brune ierr = PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 393835f5d045SPeter Brune } 393935f5d045SPeter Brune ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 39403a40ed3dSBarry Smith PetscFunctionReturn(0); 39413c7409f5SSatish Balay } 39423c7409f5SSatish Balay 39434a2ae208SSatish Balay #undef __FUNCT__ 39444a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 39453c7409f5SSatish Balay /*@C 3946f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3947d850072dSLois Curfman McInnes SNES options in the database. 39483c7409f5SSatish Balay 39493f9fe445SBarry Smith Logically Collective on SNES 3950fee21e36SBarry Smith 3951c7afd0dbSLois Curfman McInnes Input Parameters: 3952c7afd0dbSLois Curfman McInnes + snes - the SNES context 3953c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3954c7afd0dbSLois Curfman McInnes 3955d850072dSLois Curfman McInnes Notes: 3956a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3957c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3958d850072dSLois Curfman McInnes 395936851e7fSLois Curfman McInnes Level: advanced 396036851e7fSLois Curfman McInnes 39613c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3962a86d99e1SLois Curfman McInnes 3963a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 39643c7409f5SSatish Balay @*/ 39657087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 39663c7409f5SSatish Balay { 3967dfbe8321SBarry Smith PetscErrorCode ierr; 39683c7409f5SSatish Balay 39693a40ed3dSBarry Smith PetscFunctionBegin; 39700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3971639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 39721cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 397335f5d045SPeter Brune if (snes->linesearch) { 397435f5d045SPeter Brune ierr = SNESGetSNESLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 397508b6c495SPeter Brune ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 397635f5d045SPeter Brune } 397735f5d045SPeter Brune ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 39783a40ed3dSBarry Smith PetscFunctionReturn(0); 39793c7409f5SSatish Balay } 39803c7409f5SSatish Balay 39814a2ae208SSatish Balay #undef __FUNCT__ 39824a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 39839ab63eb5SSatish Balay /*@C 39843c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 39853c7409f5SSatish Balay SNES options in the database. 39863c7409f5SSatish Balay 3987c7afd0dbSLois Curfman McInnes Not Collective 3988c7afd0dbSLois Curfman McInnes 39893c7409f5SSatish Balay Input Parameter: 39903c7409f5SSatish Balay . snes - the SNES context 39913c7409f5SSatish Balay 39923c7409f5SSatish Balay Output Parameter: 39933c7409f5SSatish Balay . prefix - pointer to the prefix string used 39943c7409f5SSatish Balay 39954ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 39969ab63eb5SSatish Balay sufficient length to hold the prefix. 39979ab63eb5SSatish Balay 399836851e7fSLois Curfman McInnes Level: advanced 399936851e7fSLois Curfman McInnes 40003c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 4001a86d99e1SLois Curfman McInnes 4002a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 40033c7409f5SSatish Balay @*/ 40047087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 40053c7409f5SSatish Balay { 4006dfbe8321SBarry Smith PetscErrorCode ierr; 40073c7409f5SSatish Balay 40083a40ed3dSBarry Smith PetscFunctionBegin; 40090700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4010639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 40113a40ed3dSBarry Smith PetscFunctionReturn(0); 40123c7409f5SSatish Balay } 40133c7409f5SSatish Balay 4014b2002411SLois Curfman McInnes 40154a2ae208SSatish Balay #undef __FUNCT__ 40164a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 40173cea93caSBarry Smith /*@C 40183cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 40193cea93caSBarry Smith 40207f6c08e0SMatthew Knepley Level: advanced 40213cea93caSBarry Smith @*/ 40227087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 4023b2002411SLois Curfman McInnes { 4024e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 4025dfbe8321SBarry Smith PetscErrorCode ierr; 4026b2002411SLois Curfman McInnes 4027b2002411SLois Curfman McInnes PetscFunctionBegin; 4028b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 4029c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 4030b2002411SLois Curfman McInnes PetscFunctionReturn(0); 4031b2002411SLois Curfman McInnes } 4032da9b6338SBarry Smith 4033da9b6338SBarry Smith #undef __FUNCT__ 4034da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 40357087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 4036da9b6338SBarry Smith { 4037dfbe8321SBarry Smith PetscErrorCode ierr; 403877431f27SBarry Smith PetscInt N,i,j; 4039da9b6338SBarry Smith Vec u,uh,fh; 4040da9b6338SBarry Smith PetscScalar value; 4041da9b6338SBarry Smith PetscReal norm; 4042da9b6338SBarry Smith 4043da9b6338SBarry Smith PetscFunctionBegin; 4044da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 4045da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 4046da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 4047da9b6338SBarry Smith 4048da9b6338SBarry Smith /* currently only works for sequential */ 4049da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 4050da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 4051da9b6338SBarry Smith for (i=0; i<N; i++) { 4052da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 405377431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 4054da9b6338SBarry Smith for (j=-10; j<11; j++) { 4055ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 4056da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 40573ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 4058da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 405977431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 4060da9b6338SBarry Smith value = -value; 4061da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 4062da9b6338SBarry Smith } 4063da9b6338SBarry Smith } 40646bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 40656bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 4066da9b6338SBarry Smith PetscFunctionReturn(0); 4067da9b6338SBarry Smith } 406871f87433Sdalcinl 406971f87433Sdalcinl #undef __FUNCT__ 4070fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 407171f87433Sdalcinl /*@ 4072fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 407371f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 407471f87433Sdalcinl Newton method. 407571f87433Sdalcinl 40763f9fe445SBarry Smith Logically Collective on SNES 407771f87433Sdalcinl 407871f87433Sdalcinl Input Parameters: 407971f87433Sdalcinl + snes - SNES context 408071f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 408171f87433Sdalcinl 408264ba62caSBarry Smith Options Database: 408364ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 408464ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 408564ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 408664ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 408764ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 408864ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 408964ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 409064ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 409164ba62caSBarry Smith 409271f87433Sdalcinl Notes: 409371f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 409471f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 409571f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 409671f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 409771f87433Sdalcinl solver. 409871f87433Sdalcinl 409971f87433Sdalcinl Level: advanced 410071f87433Sdalcinl 410171f87433Sdalcinl Reference: 410271f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 410371f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 410471f87433Sdalcinl 410571f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 410671f87433Sdalcinl 4107fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 410871f87433Sdalcinl @*/ 41097087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 411071f87433Sdalcinl { 411171f87433Sdalcinl PetscFunctionBegin; 41120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4113acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 411471f87433Sdalcinl snes->ksp_ewconv = flag; 411571f87433Sdalcinl PetscFunctionReturn(0); 411671f87433Sdalcinl } 411771f87433Sdalcinl 411871f87433Sdalcinl #undef __FUNCT__ 4119fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 412071f87433Sdalcinl /*@ 4121fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 412271f87433Sdalcinl for computing relative tolerance for linear solvers within an 412371f87433Sdalcinl inexact Newton method. 412471f87433Sdalcinl 412571f87433Sdalcinl Not Collective 412671f87433Sdalcinl 412771f87433Sdalcinl Input Parameter: 412871f87433Sdalcinl . snes - SNES context 412971f87433Sdalcinl 413071f87433Sdalcinl Output Parameter: 413171f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 413271f87433Sdalcinl 413371f87433Sdalcinl Notes: 413471f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 413571f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 413671f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 413771f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 413871f87433Sdalcinl solver. 413971f87433Sdalcinl 414071f87433Sdalcinl Level: advanced 414171f87433Sdalcinl 414271f87433Sdalcinl Reference: 414371f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 414471f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 414571f87433Sdalcinl 414671f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 414771f87433Sdalcinl 4148fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 414971f87433Sdalcinl @*/ 41507087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 415171f87433Sdalcinl { 415271f87433Sdalcinl PetscFunctionBegin; 41530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 415471f87433Sdalcinl PetscValidPointer(flag,2); 415571f87433Sdalcinl *flag = snes->ksp_ewconv; 415671f87433Sdalcinl PetscFunctionReturn(0); 415771f87433Sdalcinl } 415871f87433Sdalcinl 415971f87433Sdalcinl #undef __FUNCT__ 4160fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 416171f87433Sdalcinl /*@ 4162fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 416371f87433Sdalcinl convergence criteria for the linear solvers within an inexact 416471f87433Sdalcinl Newton method. 416571f87433Sdalcinl 41663f9fe445SBarry Smith Logically Collective on SNES 416771f87433Sdalcinl 416871f87433Sdalcinl Input Parameters: 416971f87433Sdalcinl + snes - SNES context 417071f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 417171f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 417271f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 417371f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 417471f87433Sdalcinl (0 <= gamma2 <= 1) 417571f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 417671f87433Sdalcinl . alpha2 - power for safeguard 417771f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 417871f87433Sdalcinl 417971f87433Sdalcinl Note: 418071f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 418171f87433Sdalcinl 418271f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 418371f87433Sdalcinl 418471f87433Sdalcinl Level: advanced 418571f87433Sdalcinl 418671f87433Sdalcinl Reference: 418771f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 418871f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 418971f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 419071f87433Sdalcinl 419171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 419271f87433Sdalcinl 4193fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 419471f87433Sdalcinl @*/ 41957087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 419671f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 419771f87433Sdalcinl { 4198fa9f3622SBarry Smith SNESKSPEW *kctx; 419971f87433Sdalcinl PetscFunctionBegin; 42000700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4201fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4202e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 4203c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 4204c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 4205c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 4206c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 4207c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 4208c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 4209c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 421071f87433Sdalcinl 421171f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 421271f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 421371f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 421471f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 421571f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 421671f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 421771f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 421871f87433Sdalcinl 421971f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 4220e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 422171f87433Sdalcinl } 422271f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 4223e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 422471f87433Sdalcinl } 422571f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 4226e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 422771f87433Sdalcinl } 422871f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 4229e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 423071f87433Sdalcinl } 423171f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 4232e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 423371f87433Sdalcinl } 423471f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 4235e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 423671f87433Sdalcinl } 423771f87433Sdalcinl PetscFunctionReturn(0); 423871f87433Sdalcinl } 423971f87433Sdalcinl 424071f87433Sdalcinl #undef __FUNCT__ 4241fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 424271f87433Sdalcinl /*@ 4243fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 424471f87433Sdalcinl convergence criteria for the linear solvers within an inexact 424571f87433Sdalcinl Newton method. 424671f87433Sdalcinl 424771f87433Sdalcinl Not Collective 424871f87433Sdalcinl 424971f87433Sdalcinl Input Parameters: 425071f87433Sdalcinl snes - SNES context 425171f87433Sdalcinl 425271f87433Sdalcinl Output Parameters: 425371f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 425471f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 425571f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 425671f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 425771f87433Sdalcinl (0 <= gamma2 <= 1) 425871f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 425971f87433Sdalcinl . alpha2 - power for safeguard 426071f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 426171f87433Sdalcinl 426271f87433Sdalcinl Level: advanced 426371f87433Sdalcinl 426471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 426571f87433Sdalcinl 4266fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 426771f87433Sdalcinl @*/ 42687087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 426971f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 427071f87433Sdalcinl { 4271fa9f3622SBarry Smith SNESKSPEW *kctx; 427271f87433Sdalcinl PetscFunctionBegin; 42730700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4274fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4275e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 427671f87433Sdalcinl if (version) *version = kctx->version; 427771f87433Sdalcinl if (rtol_0) *rtol_0 = kctx->rtol_0; 427871f87433Sdalcinl if (rtol_max) *rtol_max = kctx->rtol_max; 427971f87433Sdalcinl if (gamma) *gamma = kctx->gamma; 428071f87433Sdalcinl if (alpha) *alpha = kctx->alpha; 428171f87433Sdalcinl if (alpha2) *alpha2 = kctx->alpha2; 428271f87433Sdalcinl if (threshold) *threshold = kctx->threshold; 428371f87433Sdalcinl PetscFunctionReturn(0); 428471f87433Sdalcinl } 428571f87433Sdalcinl 428671f87433Sdalcinl #undef __FUNCT__ 4287fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 4288fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 428971f87433Sdalcinl { 429071f87433Sdalcinl PetscErrorCode ierr; 4291fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 429271f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 429371f87433Sdalcinl 429471f87433Sdalcinl PetscFunctionBegin; 4295e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 429671f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 429771f87433Sdalcinl rtol = kctx->rtol_0; 429871f87433Sdalcinl } else { 429971f87433Sdalcinl if (kctx->version == 1) { 430071f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 430171f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 430271f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 430371f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 430471f87433Sdalcinl } else if (kctx->version == 2) { 430571f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 430671f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 430771f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 430871f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 430971f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 431071f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 431171f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 431271f87433Sdalcinl stol = PetscMax(rtol,stol); 431371f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 431471f87433Sdalcinl /* safeguard: avoid oversolving */ 431571f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 431671f87433Sdalcinl stol = PetscMax(rtol,stol); 431771f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 4318e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 431971f87433Sdalcinl } 432071f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 432171f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 432271f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 432371f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 432471f87433Sdalcinl PetscFunctionReturn(0); 432571f87433Sdalcinl } 432671f87433Sdalcinl 432771f87433Sdalcinl #undef __FUNCT__ 4328fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 4329fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 433071f87433Sdalcinl { 433171f87433Sdalcinl PetscErrorCode ierr; 4332fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 433371f87433Sdalcinl PCSide pcside; 433471f87433Sdalcinl Vec lres; 433571f87433Sdalcinl 433671f87433Sdalcinl PetscFunctionBegin; 4337e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 433871f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 433971f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 434071f87433Sdalcinl if (kctx->version == 1) { 4341b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 434271f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 434371f87433Sdalcinl /* KSP residual is true linear residual */ 434471f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 434571f87433Sdalcinl } else { 434671f87433Sdalcinl /* KSP residual is preconditioned residual */ 434771f87433Sdalcinl /* compute true linear residual norm */ 434871f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 434971f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 435071f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 435171f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 43526bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 435371f87433Sdalcinl } 435471f87433Sdalcinl } 435571f87433Sdalcinl PetscFunctionReturn(0); 435671f87433Sdalcinl } 435771f87433Sdalcinl 435871f87433Sdalcinl #undef __FUNCT__ 435971f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 436071f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 436171f87433Sdalcinl { 436271f87433Sdalcinl PetscErrorCode ierr; 436371f87433Sdalcinl 436471f87433Sdalcinl PetscFunctionBegin; 4365fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 436671f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 4367fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 436871f87433Sdalcinl PetscFunctionReturn(0); 436971f87433Sdalcinl } 43706c699258SBarry Smith 43716c699258SBarry Smith #undef __FUNCT__ 43726c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 43736c699258SBarry Smith /*@ 43746c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 43756c699258SBarry Smith 43763f9fe445SBarry Smith Logically Collective on SNES 43776c699258SBarry Smith 43786c699258SBarry Smith Input Parameters: 43796c699258SBarry Smith + snes - the preconditioner context 43806c699258SBarry Smith - dm - the dm 43816c699258SBarry Smith 43826c699258SBarry Smith Level: intermediate 43836c699258SBarry Smith 43846c699258SBarry Smith 43856c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 43866c699258SBarry Smith @*/ 43877087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 43886c699258SBarry Smith { 43896c699258SBarry Smith PetscErrorCode ierr; 4390345fed2cSBarry Smith KSP ksp; 43916cab3a1bSJed Brown SNESDM sdm; 43926c699258SBarry Smith 43936c699258SBarry Smith PetscFunctionBegin; 43940700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4395d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 43966cab3a1bSJed Brown if (snes->dm) { /* Move the SNESDM context over to the new DM unless the new DM already has one */ 43976cab3a1bSJed Brown PetscContainer oldcontainer,container; 43986cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 43996cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr); 4400116d1032SJed Brown if (oldcontainer && snes->dmAuto && !container) { 44016cab3a1bSJed Brown ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr); 44026cab3a1bSJed Brown ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr); 44036cab3a1bSJed Brown if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */ 44046cab3a1bSJed Brown sdm->originaldm = dm; 44056cab3a1bSJed Brown } 44066cab3a1bSJed Brown } 44076bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 44086cab3a1bSJed Brown } 44096c699258SBarry Smith snes->dm = dm; 4410116d1032SJed Brown snes->dmAuto = PETSC_FALSE; 4411345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4412345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4413f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 44142c155ee1SBarry Smith if (snes->pc) { 44152c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 4416c40d0f55SPeter Brune ierr = SNESSetPCSide(snes,snes->pcside);CHKERRQ(ierr); 44172c155ee1SBarry Smith } 44186c699258SBarry Smith PetscFunctionReturn(0); 44196c699258SBarry Smith } 44206c699258SBarry Smith 44216c699258SBarry Smith #undef __FUNCT__ 44226c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 44236c699258SBarry Smith /*@ 44246c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 44256c699258SBarry Smith 44263f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 44276c699258SBarry Smith 44286c699258SBarry Smith Input Parameter: 44296c699258SBarry Smith . snes - the preconditioner context 44306c699258SBarry Smith 44316c699258SBarry Smith Output Parameter: 44326c699258SBarry Smith . dm - the dm 44336c699258SBarry Smith 44346c699258SBarry Smith Level: intermediate 44356c699258SBarry Smith 44366c699258SBarry Smith 44376c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 44386c699258SBarry Smith @*/ 44397087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 44406c699258SBarry Smith { 44416cab3a1bSJed Brown PetscErrorCode ierr; 44426cab3a1bSJed Brown 44436c699258SBarry Smith PetscFunctionBegin; 44440700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 44456cab3a1bSJed Brown if (!snes->dm) { 44466cab3a1bSJed Brown ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr); 4447116d1032SJed Brown snes->dmAuto = PETSC_TRUE; 44486cab3a1bSJed Brown } 44496c699258SBarry Smith *dm = snes->dm; 44506c699258SBarry Smith PetscFunctionReturn(0); 44516c699258SBarry Smith } 44520807856dSBarry Smith 445331823bd8SMatthew G Knepley #undef __FUNCT__ 445431823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 445531823bd8SMatthew G Knepley /*@ 4456fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 445731823bd8SMatthew G Knepley 445831823bd8SMatthew G Knepley Collective on SNES 445931823bd8SMatthew G Knepley 446031823bd8SMatthew G Knepley Input Parameters: 446131823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 446231823bd8SMatthew G Knepley - pc - the preconditioner object 446331823bd8SMatthew G Knepley 446431823bd8SMatthew G Knepley Notes: 446531823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 446631823bd8SMatthew G Knepley to configure it using the API). 446731823bd8SMatthew G Knepley 446831823bd8SMatthew G Knepley Level: developer 446931823bd8SMatthew G Knepley 447031823bd8SMatthew G Knepley .keywords: SNES, set, precondition 447131823bd8SMatthew G Knepley .seealso: SNESGetPC() 447231823bd8SMatthew G Knepley @*/ 447331823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 447431823bd8SMatthew G Knepley { 447531823bd8SMatthew G Knepley PetscErrorCode ierr; 447631823bd8SMatthew G Knepley 447731823bd8SMatthew G Knepley PetscFunctionBegin; 447831823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 447931823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 448031823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 448131823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4482bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 448331823bd8SMatthew G Knepley snes->pc = pc; 448431823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 448531823bd8SMatthew G Knepley PetscFunctionReturn(0); 448631823bd8SMatthew G Knepley } 448731823bd8SMatthew G Knepley 448831823bd8SMatthew G Knepley #undef __FUNCT__ 448931823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 449031823bd8SMatthew G Knepley /*@ 4491fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 449231823bd8SMatthew G Knepley 449331823bd8SMatthew G Knepley Not Collective 449431823bd8SMatthew G Knepley 449531823bd8SMatthew G Knepley Input Parameter: 449631823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 449731823bd8SMatthew G Knepley 449831823bd8SMatthew G Knepley Output Parameter: 449931823bd8SMatthew G Knepley . pc - preconditioner context 450031823bd8SMatthew G Knepley 450131823bd8SMatthew G Knepley Level: developer 450231823bd8SMatthew G Knepley 450331823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 450431823bd8SMatthew G Knepley .seealso: SNESSetPC() 450531823bd8SMatthew G Knepley @*/ 450631823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 450731823bd8SMatthew G Knepley { 450831823bd8SMatthew G Knepley PetscErrorCode ierr; 4509a64e098fSPeter Brune const char *optionsprefix; 451031823bd8SMatthew G Knepley 451131823bd8SMatthew G Knepley PetscFunctionBegin; 451231823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 451331823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 451431823bd8SMatthew G Knepley if (!snes->pc) { 451531823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm,&snes->pc);CHKERRQ(ierr); 45164a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr); 451731823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes,snes->pc);CHKERRQ(ierr); 4518a64e098fSPeter Brune ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr); 4519a64e098fSPeter Brune ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr); 4520a64e098fSPeter Brune ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr); 452131823bd8SMatthew G Knepley } 452231823bd8SMatthew G Knepley *pc = snes->pc; 452331823bd8SMatthew G Knepley PetscFunctionReturn(0); 452431823bd8SMatthew G Knepley } 452531823bd8SMatthew G Knepley 4526c40d0f55SPeter Brune 4527c40d0f55SPeter Brune #undef __FUNCT__ 4528c40d0f55SPeter Brune #define __FUNCT__ "SNESSetPCSide" 4529c40d0f55SPeter Brune /*@ 4530c40d0f55SPeter Brune SNESSetPCSide - Sets the preconditioning side. 4531c40d0f55SPeter Brune 4532c40d0f55SPeter Brune Logically Collective on SNES 4533c40d0f55SPeter Brune 4534c40d0f55SPeter Brune Input Parameter: 4535c40d0f55SPeter Brune . snes - iterative context obtained from SNESCreate() 4536c40d0f55SPeter Brune 4537c40d0f55SPeter Brune Output Parameter: 4538c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 4539c40d0f55SPeter Brune .vb 4540c40d0f55SPeter Brune PC_LEFT - left preconditioning (default) 4541c40d0f55SPeter Brune PC_RIGHT - right preconditioning 4542c40d0f55SPeter Brune .ve 4543c40d0f55SPeter Brune 4544c40d0f55SPeter Brune Options Database Keys: 4545c40d0f55SPeter Brune . -snes_pc_side <right,left> 4546c40d0f55SPeter Brune 4547c40d0f55SPeter Brune Level: intermediate 4548c40d0f55SPeter Brune 4549c40d0f55SPeter Brune .keywords: SNES, set, right, left, side, preconditioner, flag 4550c40d0f55SPeter Brune 4551c40d0f55SPeter Brune .seealso: SNESGetPCSide(), KSPSetPCSide() 4552c40d0f55SPeter Brune @*/ 4553c40d0f55SPeter Brune PetscErrorCode SNESSetPCSide(SNES snes,PCSide side) 4554c40d0f55SPeter Brune { 4555c40d0f55SPeter Brune PetscFunctionBegin; 4556c40d0f55SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4557c40d0f55SPeter Brune PetscValidLogicalCollectiveEnum(snes,side,2); 4558c40d0f55SPeter Brune snes->pcside = side; 4559c40d0f55SPeter Brune PetscFunctionReturn(0); 4560c40d0f55SPeter Brune } 4561c40d0f55SPeter Brune 4562c40d0f55SPeter Brune #undef __FUNCT__ 4563c40d0f55SPeter Brune #define __FUNCT__ "SNESGetPCSide" 4564c40d0f55SPeter Brune /*@ 4565c40d0f55SPeter Brune SNESGetPCSide - Gets the preconditioning side. 4566c40d0f55SPeter Brune 4567c40d0f55SPeter Brune Not Collective 4568c40d0f55SPeter Brune 4569c40d0f55SPeter Brune Input Parameter: 4570c40d0f55SPeter Brune . snes - iterative context obtained from SNESCreate() 4571c40d0f55SPeter Brune 4572c40d0f55SPeter Brune Output Parameter: 4573c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 4574c40d0f55SPeter Brune .vb 4575c40d0f55SPeter Brune PC_LEFT - left preconditioning (default) 4576c40d0f55SPeter Brune PC_RIGHT - right preconditioning 4577c40d0f55SPeter Brune .ve 4578c40d0f55SPeter Brune 4579c40d0f55SPeter Brune Level: intermediate 4580c40d0f55SPeter Brune 4581c40d0f55SPeter Brune .keywords: SNES, get, right, left, side, preconditioner, flag 4582c40d0f55SPeter Brune 4583c40d0f55SPeter Brune .seealso: SNESSetPCSide(), KSPGetPCSide() 4584c40d0f55SPeter Brune @*/ 4585c40d0f55SPeter Brune PetscErrorCode SNESGetPCSide(SNES snes,PCSide *side) 4586c40d0f55SPeter Brune { 4587c40d0f55SPeter Brune PetscFunctionBegin; 4588c40d0f55SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4589c40d0f55SPeter Brune PetscValidPointer(side,2); 4590c40d0f55SPeter Brune *side = snes->pcside; 4591c40d0f55SPeter Brune PetscFunctionReturn(0); 4592c40d0f55SPeter Brune } 4593c40d0f55SPeter Brune 45949e764e56SPeter Brune #undef __FUNCT__ 4595f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch" 45969e764e56SPeter Brune /*@ 45978141a3b9SPeter Brune SNESSetSNESLineSearch - Sets the linesearch on the SNES instance. 45989e764e56SPeter Brune 45999e764e56SPeter Brune Collective on SNES 46009e764e56SPeter Brune 46019e764e56SPeter Brune Input Parameters: 46029e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 46039e764e56SPeter Brune - linesearch - the linesearch object 46049e764e56SPeter Brune 46059e764e56SPeter Brune Notes: 4606f1c6b773SPeter Brune Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example, 46079e764e56SPeter Brune to configure it using the API). 46089e764e56SPeter Brune 46099e764e56SPeter Brune Level: developer 46109e764e56SPeter Brune 46119e764e56SPeter Brune .keywords: SNES, set, linesearch 4612f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch() 46139e764e56SPeter Brune @*/ 4614f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch) 46159e764e56SPeter Brune { 46169e764e56SPeter Brune PetscErrorCode ierr; 46179e764e56SPeter Brune 46189e764e56SPeter Brune PetscFunctionBegin; 46199e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4620f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 46219e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 46229e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 4623f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 46249e764e56SPeter Brune snes->linesearch = linesearch; 46259e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 46269e764e56SPeter Brune PetscFunctionReturn(0); 46279e764e56SPeter Brune } 46289e764e56SPeter Brune 46299e764e56SPeter Brune #undef __FUNCT__ 4630f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch" 4631ea5d4fccSPeter Brune /*@C 46328141a3b9SPeter Brune SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 46338141a3b9SPeter Brune or creates a default line search instance associated with the SNES and returns it. 46349e764e56SPeter Brune 46359e764e56SPeter Brune Not Collective 46369e764e56SPeter Brune 46379e764e56SPeter Brune Input Parameter: 46389e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 46399e764e56SPeter Brune 46409e764e56SPeter Brune Output Parameter: 46419e764e56SPeter Brune . linesearch - linesearch context 46429e764e56SPeter Brune 46439e764e56SPeter Brune Level: developer 46449e764e56SPeter Brune 46459e764e56SPeter Brune .keywords: SNES, get, linesearch 4646f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch() 46479e764e56SPeter Brune @*/ 4648f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch) 46499e764e56SPeter Brune { 46509e764e56SPeter Brune PetscErrorCode ierr; 46519e764e56SPeter Brune const char *optionsprefix; 46529e764e56SPeter Brune 46539e764e56SPeter Brune PetscFunctionBegin; 46549e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 46559e764e56SPeter Brune PetscValidPointer(linesearch, 2); 46569e764e56SPeter Brune if (!snes->linesearch) { 46579e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 4658f1c6b773SPeter Brune ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr); 4659f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 4660b1dca40bSPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 46619e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 46629e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 46639e764e56SPeter Brune } 46649e764e56SPeter Brune *linesearch = snes->linesearch; 46659e764e56SPeter Brune PetscFunctionReturn(0); 46669e764e56SPeter Brune } 46679e764e56SPeter Brune 466869b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4669c6db04a5SJed Brown #include <mex.h> 467069b4f73cSBarry Smith 46718f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 46728f6e6473SBarry Smith 46730807856dSBarry Smith #undef __FUNCT__ 46740807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 46750807856dSBarry Smith /* 46760807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 46770807856dSBarry Smith SNESSetFunctionMatlab(). 46780807856dSBarry Smith 46790807856dSBarry Smith Collective on SNES 46800807856dSBarry Smith 46810807856dSBarry Smith Input Parameters: 46820807856dSBarry Smith + snes - the SNES context 46830807856dSBarry Smith - x - input vector 46840807856dSBarry Smith 46850807856dSBarry Smith Output Parameter: 46860807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 46870807856dSBarry Smith 46880807856dSBarry Smith Notes: 46890807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 46900807856dSBarry Smith implementations, so most users would not generally call this routine 46910807856dSBarry Smith themselves. 46920807856dSBarry Smith 46930807856dSBarry Smith Level: developer 46940807856dSBarry Smith 46950807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 46960807856dSBarry Smith 46970807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 469861b2408cSBarry Smith */ 46997087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 47000807856dSBarry Smith { 4701e650e774SBarry Smith PetscErrorCode ierr; 47028f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 47038f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 47048f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 470591621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 4706e650e774SBarry Smith 47070807856dSBarry Smith PetscFunctionBegin; 47080807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 47090807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 47100807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 47110807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 47120807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 47130807856dSBarry Smith 47140807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 4715e650e774SBarry Smith 471691621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4717e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4718e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 471991621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 472091621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 472191621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 47228f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 47238f6e6473SBarry Smith prhs[4] = sctx->ctx; 4724b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 4725e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4726e650e774SBarry Smith mxDestroyArray(prhs[0]); 4727e650e774SBarry Smith mxDestroyArray(prhs[1]); 4728e650e774SBarry Smith mxDestroyArray(prhs[2]); 47298f6e6473SBarry Smith mxDestroyArray(prhs[3]); 4730e650e774SBarry Smith mxDestroyArray(plhs[0]); 47310807856dSBarry Smith PetscFunctionReturn(0); 47320807856dSBarry Smith } 47330807856dSBarry Smith 47340807856dSBarry Smith 47350807856dSBarry Smith #undef __FUNCT__ 47360807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 473761b2408cSBarry Smith /* 47380807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 47390807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4740e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 47410807856dSBarry Smith 47420807856dSBarry Smith Logically Collective on SNES 47430807856dSBarry Smith 47440807856dSBarry Smith Input Parameters: 47450807856dSBarry Smith + snes - the SNES context 47460807856dSBarry Smith . r - vector to store function value 47470807856dSBarry Smith - func - function evaluation routine 47480807856dSBarry Smith 47490807856dSBarry Smith Calling sequence of func: 475061b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 47510807856dSBarry Smith 47520807856dSBarry Smith 47530807856dSBarry Smith Notes: 47540807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 47550807856dSBarry Smith $ f'(x) x = -f(x), 47560807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 47570807856dSBarry Smith 47580807856dSBarry Smith Level: beginner 47590807856dSBarry Smith 47600807856dSBarry Smith .keywords: SNES, nonlinear, set, function 47610807856dSBarry Smith 47620807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 476361b2408cSBarry Smith */ 47647087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 47650807856dSBarry Smith { 47660807856dSBarry Smith PetscErrorCode ierr; 47678f6e6473SBarry Smith SNESMatlabContext *sctx; 47680807856dSBarry Smith 47690807856dSBarry Smith PetscFunctionBegin; 47708f6e6473SBarry Smith /* currently sctx is memory bleed */ 47718f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 47728f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 47738f6e6473SBarry Smith /* 47748f6e6473SBarry Smith This should work, but it doesn't 47758f6e6473SBarry Smith sctx->ctx = ctx; 47768f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 47778f6e6473SBarry Smith */ 47788f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 47798f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 47800807856dSBarry Smith PetscFunctionReturn(0); 47810807856dSBarry Smith } 478269b4f73cSBarry Smith 478361b2408cSBarry Smith #undef __FUNCT__ 478461b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 478561b2408cSBarry Smith /* 478661b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 478761b2408cSBarry Smith SNESSetJacobianMatlab(). 478861b2408cSBarry Smith 478961b2408cSBarry Smith Collective on SNES 479061b2408cSBarry Smith 479161b2408cSBarry Smith Input Parameters: 479261b2408cSBarry Smith + snes - the SNES context 479361b2408cSBarry Smith . x - input vector 479461b2408cSBarry Smith . A, B - the matrices 479561b2408cSBarry Smith - ctx - user context 479661b2408cSBarry Smith 479761b2408cSBarry Smith Output Parameter: 479861b2408cSBarry Smith . flag - structure of the matrix 479961b2408cSBarry Smith 480061b2408cSBarry Smith Level: developer 480161b2408cSBarry Smith 480261b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 480361b2408cSBarry Smith 480461b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 480561b2408cSBarry Smith @*/ 48067087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 480761b2408cSBarry Smith { 480861b2408cSBarry Smith PetscErrorCode ierr; 480961b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 481061b2408cSBarry Smith int nlhs = 2,nrhs = 6; 481161b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 481261b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 481361b2408cSBarry Smith 481461b2408cSBarry Smith PetscFunctionBegin; 481561b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 481661b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 481761b2408cSBarry Smith 481861b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 481961b2408cSBarry Smith 482061b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 482161b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 482261b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 482361b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 482461b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 482561b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 482661b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 482761b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 482861b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 482961b2408cSBarry Smith prhs[5] = sctx->ctx; 4830b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 483161b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 483261b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 483361b2408cSBarry Smith mxDestroyArray(prhs[0]); 483461b2408cSBarry Smith mxDestroyArray(prhs[1]); 483561b2408cSBarry Smith mxDestroyArray(prhs[2]); 483661b2408cSBarry Smith mxDestroyArray(prhs[3]); 483761b2408cSBarry Smith mxDestroyArray(prhs[4]); 483861b2408cSBarry Smith mxDestroyArray(plhs[0]); 483961b2408cSBarry Smith mxDestroyArray(plhs[1]); 484061b2408cSBarry Smith PetscFunctionReturn(0); 484161b2408cSBarry Smith } 484261b2408cSBarry Smith 484361b2408cSBarry Smith 484461b2408cSBarry Smith #undef __FUNCT__ 484561b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 484661b2408cSBarry Smith /* 484761b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 484861b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4849e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 485061b2408cSBarry Smith 485161b2408cSBarry Smith Logically Collective on SNES 485261b2408cSBarry Smith 485361b2408cSBarry Smith Input Parameters: 485461b2408cSBarry Smith + snes - the SNES context 485561b2408cSBarry Smith . A,B - Jacobian matrices 485661b2408cSBarry Smith . func - function evaluation routine 485761b2408cSBarry Smith - ctx - user context 485861b2408cSBarry Smith 485961b2408cSBarry Smith Calling sequence of func: 486061b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 486161b2408cSBarry Smith 486261b2408cSBarry Smith 486361b2408cSBarry Smith Level: developer 486461b2408cSBarry Smith 486561b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 486661b2408cSBarry Smith 486761b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 486861b2408cSBarry Smith */ 48697087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 487061b2408cSBarry Smith { 487161b2408cSBarry Smith PetscErrorCode ierr; 487261b2408cSBarry Smith SNESMatlabContext *sctx; 487361b2408cSBarry Smith 487461b2408cSBarry Smith PetscFunctionBegin; 487561b2408cSBarry Smith /* currently sctx is memory bleed */ 487661b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 487761b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 487861b2408cSBarry Smith /* 487961b2408cSBarry Smith This should work, but it doesn't 488061b2408cSBarry Smith sctx->ctx = ctx; 488161b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 488261b2408cSBarry Smith */ 488361b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 488461b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 488561b2408cSBarry Smith PetscFunctionReturn(0); 488661b2408cSBarry Smith } 488769b4f73cSBarry Smith 4888f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4889f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4890f9eb7ae2SShri Abhyankar /* 4891f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4892f9eb7ae2SShri Abhyankar 4893f9eb7ae2SShri Abhyankar Collective on SNES 4894f9eb7ae2SShri Abhyankar 4895f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4896f9eb7ae2SShri Abhyankar @*/ 48977087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4898f9eb7ae2SShri Abhyankar { 4899f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 490048f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4901f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4902f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4903f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4904f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4905f9eb7ae2SShri Abhyankar 4906f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4907f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4908f9eb7ae2SShri Abhyankar 4909f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4910f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4911f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4912f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4913f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4914f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4915f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4916f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4917f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4918f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4919f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4920f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4921f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4922f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4923f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4924f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4925f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4926f9eb7ae2SShri Abhyankar } 4927f9eb7ae2SShri Abhyankar 4928f9eb7ae2SShri Abhyankar 4929f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4930f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4931f9eb7ae2SShri Abhyankar /* 4932e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4933f9eb7ae2SShri Abhyankar 4934f9eb7ae2SShri Abhyankar Level: developer 4935f9eb7ae2SShri Abhyankar 4936f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4937f9eb7ae2SShri Abhyankar 4938f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4939f9eb7ae2SShri Abhyankar */ 49407087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4941f9eb7ae2SShri Abhyankar { 4942f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4943f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4944f9eb7ae2SShri Abhyankar 4945f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4946f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4947f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4948f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4949f9eb7ae2SShri Abhyankar /* 4950f9eb7ae2SShri Abhyankar This should work, but it doesn't 4951f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4952f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4953f9eb7ae2SShri Abhyankar */ 4954f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4955f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4956f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4957f9eb7ae2SShri Abhyankar } 4958f9eb7ae2SShri Abhyankar 495969b4f73cSBarry Smith #endif 4960