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 502459f5d12SBarry 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); 646459f5d12SBarry Smith if (flg) { 647459f5d12SBarry Smith PetscDrawLG ctx; 648459f5d12SBarry Smith 649459f5d12SBarry Smith ierr = SNESMonitorLGCreate(0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&ctx);CHKERRQ(ierr); 650459f5d12SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))SNESMonitorLGDestroy);CHKERRQ(ierr); 651459f5d12SBarry 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); 654459f5d12SBarry Smith if (flg) { 655459f5d12SBarry Smith PetscViewer ctx; 656e24b481bSBarry Smith 657459f5d12SBarry Smith ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&ctx);CHKERRQ(ierr); 658459f5d12SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 659459f5d12SBarry 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; 675*97584545SPeter Brune ierr = PetscOptionsBool("-snes_fd_function","Use finite differences (slow) to compute function from user objective","SNESDefaultObjectiveComputeFunctionFD",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 676*97584545SPeter Brune if (flg) { 677*97584545SPeter Brune ierr = SNESSetFunction(snes,PETSC_NULL,SNESDefaultObjectiveComputeFunctionFD,PETSC_NULL);CHKERRQ(ierr); 678*97584545SPeter Brune } 679*97584545SPeter Brune 680*97584545SPeter Brune flg = PETSC_FALSE; 68144848bc4SPeter Brune ierr = PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESDefaultComputeJacobianColor",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 68244848bc4SPeter Brune if (flg) { 68344848bc4SPeter Brune void *functx; 68444848bc4SPeter Brune ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 6850171d955SPeter Brune ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobianColor,0);CHKERRQ(ierr); 68644848bc4SPeter Brune ierr = PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr); 68744848bc4SPeter Brune } 68844848bc4SPeter Brune 689aa3661deSLisandro Dalcin flg = PETSC_FALSE; 690d8f46077SPeter 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); 691d8f46077SPeter Brune if (flg && snes->mf_operator) { 692a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 693d8f46077SPeter Brune snes->mf = PETSC_TRUE; 694a8248277SBarry Smith } 695aa3661deSLisandro Dalcin flg = PETSC_FALSE; 696d8f46077SPeter Brune ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&snes->mf,&flg);CHKERRQ(ierr); 697d8f46077SPeter Brune if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE; 698d8f46077SPeter Brune ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,0);CHKERRQ(ierr); 699d28543b3SPeter Brune 700c40d0f55SPeter Brune flg = PETSC_FALSE; 701c40d0f55SPeter Brune ierr = SNESGetPCSide(snes,&pcside); 702c40d0f55SPeter Brune ierr = PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);CHKERRQ(ierr); 703c40d0f55SPeter Brune if (flg) {ierr = SNESSetPCSide(snes,pcside);CHKERRQ(ierr);} 704c40d0f55SPeter Brune 70589b92e6fSPeter Brune /* GS Options */ 70689b92e6fSPeter Brune ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr); 70789b92e6fSPeter Brune 70876b2cf59SMatthew Knepley for (i = 0; i < numberofsetfromoptions; i++) { 70976b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 71076b2cf59SMatthew Knepley } 71176b2cf59SMatthew Knepley 712e7788613SBarry Smith if (snes->ops->setfromoptions) { 713e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 714639f9d9dSBarry Smith } 7155d973c19SBarry Smith 7165d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 7175d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 718b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 7194bbc92c1SBarry Smith 7201cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 721aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 722aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 72385385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 72493993e2dSLois Curfman McInnes 7259e764e56SPeter Brune if (!snes->linesearch) { 726f1c6b773SPeter Brune ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 7279e764e56SPeter Brune } 728f1c6b773SPeter Brune ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr); 7299e764e56SPeter Brune 73051e86f29SPeter Brune /* if someone has set the SNES PC type, create it. */ 73151e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 73251e86f29SPeter Brune ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 73351e86f29SPeter Brune if (pcset && (!snes->pc)) { 73451e86f29SPeter Brune ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr); 73551e86f29SPeter Brune } 7363a40ed3dSBarry Smith PetscFunctionReturn(0); 7379b94acceSBarry Smith } 7389b94acceSBarry Smith 739d25893d9SBarry Smith #undef __FUNCT__ 740d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 741d25893d9SBarry Smith /*@ 742d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 743d25893d9SBarry Smith the nonlinear solvers. 744d25893d9SBarry Smith 745d25893d9SBarry Smith Logically Collective on SNES 746d25893d9SBarry Smith 747d25893d9SBarry Smith Input Parameters: 748d25893d9SBarry Smith + snes - the SNES context 749d25893d9SBarry Smith . compute - function to compute the context 750d25893d9SBarry Smith - destroy - function to destroy the context 751d25893d9SBarry Smith 752d25893d9SBarry Smith Level: intermediate 753d25893d9SBarry Smith 754d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 755d25893d9SBarry Smith 756d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 757d25893d9SBarry Smith @*/ 758d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 759d25893d9SBarry Smith { 760d25893d9SBarry Smith PetscFunctionBegin; 761d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 762d25893d9SBarry Smith snes->ops->usercompute = compute; 763d25893d9SBarry Smith snes->ops->userdestroy = destroy; 764d25893d9SBarry Smith PetscFunctionReturn(0); 765d25893d9SBarry Smith } 766a847f771SSatish Balay 7674a2ae208SSatish Balay #undef __FUNCT__ 7684a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 769b07ff414SBarry Smith /*@ 7709b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 7719b94acceSBarry Smith the nonlinear solvers. 7729b94acceSBarry Smith 7733f9fe445SBarry Smith Logically Collective on SNES 774fee21e36SBarry Smith 775c7afd0dbSLois Curfman McInnes Input Parameters: 776c7afd0dbSLois Curfman McInnes + snes - the SNES context 777c7afd0dbSLois Curfman McInnes - usrP - optional user context 778c7afd0dbSLois Curfman McInnes 77936851e7fSLois Curfman McInnes Level: intermediate 78036851e7fSLois Curfman McInnes 7819b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 7829b94acceSBarry Smith 783ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext() 7849b94acceSBarry Smith @*/ 7857087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 7869b94acceSBarry Smith { 7871b2093e4SBarry Smith PetscErrorCode ierr; 788b07ff414SBarry Smith KSP ksp; 7891b2093e4SBarry Smith 7903a40ed3dSBarry Smith PetscFunctionBegin; 7910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 792b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 793b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 7949b94acceSBarry Smith snes->user = usrP; 7953a40ed3dSBarry Smith PetscFunctionReturn(0); 7969b94acceSBarry Smith } 79774679c65SBarry Smith 7984a2ae208SSatish Balay #undef __FUNCT__ 7994a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 800b07ff414SBarry Smith /*@ 8019b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 8029b94acceSBarry Smith nonlinear solvers. 8039b94acceSBarry Smith 804c7afd0dbSLois Curfman McInnes Not Collective 805c7afd0dbSLois Curfman McInnes 8069b94acceSBarry Smith Input Parameter: 8079b94acceSBarry Smith . snes - SNES context 8089b94acceSBarry Smith 8099b94acceSBarry Smith Output Parameter: 8109b94acceSBarry Smith . usrP - user context 8119b94acceSBarry Smith 81236851e7fSLois Curfman McInnes Level: intermediate 81336851e7fSLois Curfman McInnes 8149b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 8159b94acceSBarry Smith 8169b94acceSBarry Smith .seealso: SNESSetApplicationContext() 8179b94acceSBarry Smith @*/ 818e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 8199b94acceSBarry Smith { 8203a40ed3dSBarry Smith PetscFunctionBegin; 8210700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 822e71120c6SJed Brown *(void**)usrP = snes->user; 8233a40ed3dSBarry Smith PetscFunctionReturn(0); 8249b94acceSBarry Smith } 82574679c65SBarry Smith 8264a2ae208SSatish Balay #undef __FUNCT__ 8274a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 8289b94acceSBarry Smith /*@ 829c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 830c8228a4eSBarry Smith at this time. 8319b94acceSBarry Smith 832c7afd0dbSLois Curfman McInnes Not Collective 833c7afd0dbSLois Curfman McInnes 8349b94acceSBarry Smith Input Parameter: 8359b94acceSBarry Smith . snes - SNES context 8369b94acceSBarry Smith 8379b94acceSBarry Smith Output Parameter: 8389b94acceSBarry Smith . iter - iteration number 8399b94acceSBarry Smith 840c8228a4eSBarry Smith Notes: 841c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 842c8228a4eSBarry Smith 843c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 84408405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 84508405cd6SLois Curfman McInnes .vb 84608405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 84708405cd6SLois Curfman McInnes if (!(it % 2)) { 84808405cd6SLois Curfman McInnes [compute Jacobian here] 84908405cd6SLois Curfman McInnes } 85008405cd6SLois Curfman McInnes .ve 851c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 85208405cd6SLois Curfman McInnes recomputed every second SNES iteration. 853c8228a4eSBarry Smith 85436851e7fSLois Curfman McInnes Level: intermediate 85536851e7fSLois Curfman McInnes 8562b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 8572b668275SBarry Smith 858b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 8599b94acceSBarry Smith @*/ 8607087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 8619b94acceSBarry Smith { 8623a40ed3dSBarry Smith PetscFunctionBegin; 8630700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8644482741eSBarry Smith PetscValidIntPointer(iter,2); 8659b94acceSBarry Smith *iter = snes->iter; 8663a40ed3dSBarry Smith PetscFunctionReturn(0); 8679b94acceSBarry Smith } 86874679c65SBarry Smith 8694a2ae208SSatish Balay #undef __FUNCT__ 870360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber" 871360c497dSPeter Brune /*@ 872360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 873360c497dSPeter Brune 874360c497dSPeter Brune Not Collective 875360c497dSPeter Brune 876360c497dSPeter Brune Input Parameter: 877360c497dSPeter Brune . snes - SNES context 878360c497dSPeter Brune . iter - iteration number 879360c497dSPeter Brune 880360c497dSPeter Brune Level: developer 881360c497dSPeter Brune 882360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number, 883360c497dSPeter Brune 884360c497dSPeter Brune .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 885360c497dSPeter Brune @*/ 886360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 887360c497dSPeter Brune { 888360c497dSPeter Brune PetscErrorCode ierr; 889360c497dSPeter Brune 890360c497dSPeter Brune PetscFunctionBegin; 891360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 892360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 893360c497dSPeter Brune snes->iter = iter; 894360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 895360c497dSPeter Brune PetscFunctionReturn(0); 896360c497dSPeter Brune } 897360c497dSPeter Brune 898360c497dSPeter Brune #undef __FUNCT__ 8994a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 9009b94acceSBarry Smith /*@ 9019b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 9029b94acceSBarry Smith with SNESSSetFunction(). 9039b94acceSBarry Smith 904c7afd0dbSLois Curfman McInnes Collective on SNES 905c7afd0dbSLois Curfman McInnes 9069b94acceSBarry Smith Input Parameter: 9079b94acceSBarry Smith . snes - SNES context 9089b94acceSBarry Smith 9099b94acceSBarry Smith Output Parameter: 9109b94acceSBarry Smith . fnorm - 2-norm of function 9119b94acceSBarry Smith 91236851e7fSLois Curfman McInnes Level: intermediate 91336851e7fSLois Curfman McInnes 9149b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 915a86d99e1SLois Curfman McInnes 916b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 9179b94acceSBarry Smith @*/ 9187087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 9199b94acceSBarry Smith { 9203a40ed3dSBarry Smith PetscFunctionBegin; 9210700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9224482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 9239b94acceSBarry Smith *fnorm = snes->norm; 9243a40ed3dSBarry Smith PetscFunctionReturn(0); 9259b94acceSBarry Smith } 92674679c65SBarry Smith 927360c497dSPeter Brune 928360c497dSPeter Brune #undef __FUNCT__ 929360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm" 930360c497dSPeter Brune /*@ 931360c497dSPeter Brune SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm(). 932360c497dSPeter Brune 933360c497dSPeter Brune Collective on SNES 934360c497dSPeter Brune 935360c497dSPeter Brune Input Parameter: 936360c497dSPeter Brune . snes - SNES context 937360c497dSPeter Brune . fnorm - 2-norm of function 938360c497dSPeter Brune 939360c497dSPeter Brune Level: developer 940360c497dSPeter Brune 941360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm 942360c497dSPeter Brune 943360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm(). 944360c497dSPeter Brune @*/ 945360c497dSPeter Brune PetscErrorCode SNESSetFunctionNorm(SNES snes,PetscReal fnorm) 946360c497dSPeter Brune { 947360c497dSPeter Brune 948360c497dSPeter Brune PetscErrorCode ierr; 949360c497dSPeter Brune 950360c497dSPeter Brune PetscFunctionBegin; 951360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 952360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 953360c497dSPeter Brune snes->norm = fnorm; 954360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 955360c497dSPeter Brune PetscFunctionReturn(0); 956360c497dSPeter Brune } 957360c497dSPeter Brune 9584a2ae208SSatish Balay #undef __FUNCT__ 959b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 9609b94acceSBarry Smith /*@ 961b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 9629b94acceSBarry Smith attempted by the nonlinear solver. 9639b94acceSBarry Smith 964c7afd0dbSLois Curfman McInnes Not Collective 965c7afd0dbSLois Curfman McInnes 9669b94acceSBarry Smith Input Parameter: 9679b94acceSBarry Smith . snes - SNES context 9689b94acceSBarry Smith 9699b94acceSBarry Smith Output Parameter: 9709b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 9719b94acceSBarry Smith 972c96a6f78SLois Curfman McInnes Notes: 973c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 974c96a6f78SLois Curfman McInnes 97536851e7fSLois Curfman McInnes Level: intermediate 97636851e7fSLois Curfman McInnes 9779b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 97858ebbce7SBarry Smith 979e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 98058ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 9819b94acceSBarry Smith @*/ 9827087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 9839b94acceSBarry Smith { 9843a40ed3dSBarry Smith PetscFunctionBegin; 9850700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9864482741eSBarry Smith PetscValidIntPointer(nfails,2); 98750ffb88aSMatthew Knepley *nfails = snes->numFailures; 98850ffb88aSMatthew Knepley PetscFunctionReturn(0); 98950ffb88aSMatthew Knepley } 99050ffb88aSMatthew Knepley 99150ffb88aSMatthew Knepley #undef __FUNCT__ 992b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 99350ffb88aSMatthew Knepley /*@ 994b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 99550ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 99650ffb88aSMatthew Knepley 99750ffb88aSMatthew Knepley Not Collective 99850ffb88aSMatthew Knepley 99950ffb88aSMatthew Knepley Input Parameters: 100050ffb88aSMatthew Knepley + snes - SNES context 100150ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 100250ffb88aSMatthew Knepley 100350ffb88aSMatthew Knepley Level: intermediate 100450ffb88aSMatthew Knepley 100550ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 100658ebbce7SBarry Smith 1007e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 100858ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 100950ffb88aSMatthew Knepley @*/ 10107087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 101150ffb88aSMatthew Knepley { 101250ffb88aSMatthew Knepley PetscFunctionBegin; 10130700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 101450ffb88aSMatthew Knepley snes->maxFailures = maxFails; 101550ffb88aSMatthew Knepley PetscFunctionReturn(0); 101650ffb88aSMatthew Knepley } 101750ffb88aSMatthew Knepley 101850ffb88aSMatthew Knepley #undef __FUNCT__ 1019b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 102050ffb88aSMatthew Knepley /*@ 1021b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 102250ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 102350ffb88aSMatthew Knepley 102450ffb88aSMatthew Knepley Not Collective 102550ffb88aSMatthew Knepley 102650ffb88aSMatthew Knepley Input Parameter: 102750ffb88aSMatthew Knepley . snes - SNES context 102850ffb88aSMatthew Knepley 102950ffb88aSMatthew Knepley Output Parameter: 103050ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 103150ffb88aSMatthew Knepley 103250ffb88aSMatthew Knepley Level: intermediate 103350ffb88aSMatthew Knepley 103450ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 103558ebbce7SBarry Smith 1036e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 103758ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 103858ebbce7SBarry Smith 103950ffb88aSMatthew Knepley @*/ 10407087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 104150ffb88aSMatthew Knepley { 104250ffb88aSMatthew Knepley PetscFunctionBegin; 10430700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10444482741eSBarry Smith PetscValidIntPointer(maxFails,2); 104550ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 10463a40ed3dSBarry Smith PetscFunctionReturn(0); 10479b94acceSBarry Smith } 1048a847f771SSatish Balay 10494a2ae208SSatish Balay #undef __FUNCT__ 10502541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 10512541af92SBarry Smith /*@ 10522541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 10532541af92SBarry Smith done by SNES. 10542541af92SBarry Smith 10552541af92SBarry Smith Not Collective 10562541af92SBarry Smith 10572541af92SBarry Smith Input Parameter: 10582541af92SBarry Smith . snes - SNES context 10592541af92SBarry Smith 10602541af92SBarry Smith Output Parameter: 10612541af92SBarry Smith . nfuncs - number of evaluations 10622541af92SBarry Smith 10632541af92SBarry Smith Level: intermediate 10642541af92SBarry Smith 10652541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 106658ebbce7SBarry Smith 1067e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 10682541af92SBarry Smith @*/ 10697087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 10702541af92SBarry Smith { 10712541af92SBarry Smith PetscFunctionBegin; 10720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10732541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 10742541af92SBarry Smith *nfuncs = snes->nfuncs; 10752541af92SBarry Smith PetscFunctionReturn(0); 10762541af92SBarry Smith } 10772541af92SBarry Smith 10782541af92SBarry Smith #undef __FUNCT__ 10793d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 10803d4c4710SBarry Smith /*@ 10813d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 10823d4c4710SBarry Smith linear solvers. 10833d4c4710SBarry Smith 10843d4c4710SBarry Smith Not Collective 10853d4c4710SBarry Smith 10863d4c4710SBarry Smith Input Parameter: 10873d4c4710SBarry Smith . snes - SNES context 10883d4c4710SBarry Smith 10893d4c4710SBarry Smith Output Parameter: 10903d4c4710SBarry Smith . nfails - number of failed solves 10913d4c4710SBarry Smith 10923d4c4710SBarry Smith Notes: 10933d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 10943d4c4710SBarry Smith 10953d4c4710SBarry Smith Level: intermediate 10963d4c4710SBarry Smith 10973d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 109858ebbce7SBarry Smith 1099e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 11003d4c4710SBarry Smith @*/ 11017087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 11023d4c4710SBarry Smith { 11033d4c4710SBarry Smith PetscFunctionBegin; 11040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11053d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 11063d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 11073d4c4710SBarry Smith PetscFunctionReturn(0); 11083d4c4710SBarry Smith } 11093d4c4710SBarry Smith 11103d4c4710SBarry Smith #undef __FUNCT__ 11113d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 11123d4c4710SBarry Smith /*@ 11133d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 11143d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 11153d4c4710SBarry Smith 11163f9fe445SBarry Smith Logically Collective on SNES 11173d4c4710SBarry Smith 11183d4c4710SBarry Smith Input Parameters: 11193d4c4710SBarry Smith + snes - SNES context 11203d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 11213d4c4710SBarry Smith 11223d4c4710SBarry Smith Level: intermediate 11233d4c4710SBarry Smith 1124a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 11253d4c4710SBarry Smith 11263d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 11273d4c4710SBarry Smith 112858ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 11293d4c4710SBarry Smith @*/ 11307087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 11313d4c4710SBarry Smith { 11323d4c4710SBarry Smith PetscFunctionBegin; 11330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1134c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 11353d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 11363d4c4710SBarry Smith PetscFunctionReturn(0); 11373d4c4710SBarry Smith } 11383d4c4710SBarry Smith 11393d4c4710SBarry Smith #undef __FUNCT__ 11403d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 11413d4c4710SBarry Smith /*@ 11423d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 11433d4c4710SBarry Smith are allowed before SNES terminates 11443d4c4710SBarry Smith 11453d4c4710SBarry Smith Not Collective 11463d4c4710SBarry Smith 11473d4c4710SBarry Smith Input Parameter: 11483d4c4710SBarry Smith . snes - SNES context 11493d4c4710SBarry Smith 11503d4c4710SBarry Smith Output Parameter: 11513d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 11523d4c4710SBarry Smith 11533d4c4710SBarry Smith Level: intermediate 11543d4c4710SBarry Smith 11553d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 11563d4c4710SBarry Smith 11573d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 11583d4c4710SBarry Smith 1159e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 11603d4c4710SBarry Smith @*/ 11617087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 11623d4c4710SBarry Smith { 11633d4c4710SBarry Smith PetscFunctionBegin; 11640700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11653d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 11663d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 11673d4c4710SBarry Smith PetscFunctionReturn(0); 11683d4c4710SBarry Smith } 11693d4c4710SBarry Smith 11703d4c4710SBarry Smith #undef __FUNCT__ 1171b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 1172c96a6f78SLois Curfman McInnes /*@ 1173b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1174c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1175c96a6f78SLois Curfman McInnes 1176c7afd0dbSLois Curfman McInnes Not Collective 1177c7afd0dbSLois Curfman McInnes 1178c96a6f78SLois Curfman McInnes Input Parameter: 1179c96a6f78SLois Curfman McInnes . snes - SNES context 1180c96a6f78SLois Curfman McInnes 1181c96a6f78SLois Curfman McInnes Output Parameter: 1182c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1183c96a6f78SLois Curfman McInnes 1184c96a6f78SLois Curfman McInnes Notes: 1185c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1186c96a6f78SLois Curfman McInnes 118736851e7fSLois Curfman McInnes Level: intermediate 118836851e7fSLois Curfman McInnes 1189c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 11902b668275SBarry Smith 11918c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 1192c96a6f78SLois Curfman McInnes @*/ 11937087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 1194c96a6f78SLois Curfman McInnes { 11953a40ed3dSBarry Smith PetscFunctionBegin; 11960700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11974482741eSBarry Smith PetscValidIntPointer(lits,2); 1198c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 11993a40ed3dSBarry Smith PetscFunctionReturn(0); 1200c96a6f78SLois Curfman McInnes } 1201c96a6f78SLois Curfman McInnes 12024a2ae208SSatish Balay #undef __FUNCT__ 120394b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 120452baeb72SSatish Balay /*@ 120594b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 12069b94acceSBarry Smith 120794b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 1208c7afd0dbSLois Curfman McInnes 12099b94acceSBarry Smith Input Parameter: 12109b94acceSBarry Smith . snes - the SNES context 12119b94acceSBarry Smith 12129b94acceSBarry Smith Output Parameter: 121394b7f48cSBarry Smith . ksp - the KSP context 12149b94acceSBarry Smith 12159b94acceSBarry Smith Notes: 121694b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 12179b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 12182999313aSBarry Smith PC contexts as well. 12199b94acceSBarry Smith 122036851e7fSLois Curfman McInnes Level: beginner 122136851e7fSLois Curfman McInnes 122294b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 12239b94acceSBarry Smith 12242999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 12259b94acceSBarry Smith @*/ 12267087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 12279b94acceSBarry Smith { 12281cee3971SBarry Smith PetscErrorCode ierr; 12291cee3971SBarry Smith 12303a40ed3dSBarry Smith PetscFunctionBegin; 12310700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12324482741eSBarry Smith PetscValidPointer(ksp,2); 12331cee3971SBarry Smith 12341cee3971SBarry Smith if (!snes->ksp) { 12351cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 12361cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 12371cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 12381cee3971SBarry Smith } 123994b7f48cSBarry Smith *ksp = snes->ksp; 12403a40ed3dSBarry Smith PetscFunctionReturn(0); 12419b94acceSBarry Smith } 124282bf6240SBarry Smith 12434a2ae208SSatish Balay #undef __FUNCT__ 12442999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 12452999313aSBarry Smith /*@ 12462999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 12472999313aSBarry Smith 12482999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 12492999313aSBarry Smith 12502999313aSBarry Smith Input Parameters: 12512999313aSBarry Smith + snes - the SNES context 12522999313aSBarry Smith - ksp - the KSP context 12532999313aSBarry Smith 12542999313aSBarry Smith Notes: 12552999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 12562999313aSBarry Smith so this routine is rarely needed. 12572999313aSBarry Smith 12582999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 12592999313aSBarry Smith decreased by one. 12602999313aSBarry Smith 12612999313aSBarry Smith Level: developer 12622999313aSBarry Smith 12632999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 12642999313aSBarry Smith 12652999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 12662999313aSBarry Smith @*/ 12677087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 12682999313aSBarry Smith { 12692999313aSBarry Smith PetscErrorCode ierr; 12702999313aSBarry Smith 12712999313aSBarry Smith PetscFunctionBegin; 12720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12730700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 12742999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 12757dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1276906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 12772999313aSBarry Smith snes->ksp = ksp; 12782999313aSBarry Smith PetscFunctionReturn(0); 12792999313aSBarry Smith } 12802999313aSBarry Smith 12817adad957SLisandro Dalcin #if 0 12822999313aSBarry Smith #undef __FUNCT__ 12834a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 12846849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1285e24b481bSBarry Smith { 1286e24b481bSBarry Smith PetscFunctionBegin; 1287e24b481bSBarry Smith PetscFunctionReturn(0); 1288e24b481bSBarry Smith } 12897adad957SLisandro Dalcin #endif 1290e24b481bSBarry Smith 12919b94acceSBarry Smith /* -----------------------------------------------------------*/ 12924a2ae208SSatish Balay #undef __FUNCT__ 12934a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 129452baeb72SSatish Balay /*@ 12959b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 12969b94acceSBarry Smith 1297c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1298c7afd0dbSLois Curfman McInnes 1299c7afd0dbSLois Curfman McInnes Input Parameters: 1300906ed7ccSBarry Smith . comm - MPI communicator 13019b94acceSBarry Smith 13029b94acceSBarry Smith Output Parameter: 13039b94acceSBarry Smith . outsnes - the new SNES context 13049b94acceSBarry Smith 1305c7afd0dbSLois Curfman McInnes Options Database Keys: 1306c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1307c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1308c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1309c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1310c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1311c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1312c1f60f51SBarry Smith 131336851e7fSLois Curfman McInnes Level: beginner 131436851e7fSLois Curfman McInnes 13159b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 13169b94acceSBarry Smith 1317a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1318a8054027SBarry Smith 13199b94acceSBarry Smith @*/ 13207087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 13219b94acceSBarry Smith { 1322dfbe8321SBarry Smith PetscErrorCode ierr; 13239b94acceSBarry Smith SNES snes; 1324fa9f3622SBarry Smith SNESKSPEW *kctx; 132537fcc0dbSBarry Smith 13263a40ed3dSBarry Smith PetscFunctionBegin; 1327ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 13288ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 13298ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 13308ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 13318ba1e511SMatthew Knepley #endif 13328ba1e511SMatthew Knepley 13333194b578SJed Brown ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 13347adad957SLisandro Dalcin 133585385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 13362c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 133788976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 13389b94acceSBarry Smith snes->max_its = 50; 13399750a799SBarry Smith snes->max_funcs = 10000; 13409b94acceSBarry Smith snes->norm = 0.0; 1341fdacfa88SPeter Brune snes->normtype = SNES_NORM_FUNCTION; 1342b4874afaSBarry Smith snes->rtol = 1.e-8; 1343b4874afaSBarry Smith snes->ttol = 0.0; 134470441072SBarry Smith snes->abstol = 1.e-50; 1345c60f73f4SPeter Brune snes->stol = 1.e-8; 13464b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 13479b94acceSBarry Smith snes->nfuncs = 0; 134850ffb88aSMatthew Knepley snes->numFailures = 0; 134950ffb88aSMatthew Knepley snes->maxFailures = 1; 13507a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1351e35cf81dSBarry Smith snes->lagjacobian = 1; 1352a8054027SBarry Smith snes->lagpreconditioner = 1; 1353639f9d9dSBarry Smith snes->numbermonitors = 0; 13549b94acceSBarry Smith snes->data = 0; 13554dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1356186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 13576f24a144SLois Curfman McInnes snes->nwork = 0; 135858c9b817SLisandro Dalcin snes->work = 0; 135958c9b817SLisandro Dalcin snes->nvwork = 0; 136058c9b817SLisandro Dalcin snes->vwork = 0; 1361758f92a0SBarry Smith snes->conv_hist_len = 0; 1362758f92a0SBarry Smith snes->conv_hist_max = 0; 1363758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1364758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1365758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1366e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1367e4ed7901SPeter Brune snes->norm_init = 0.; 1368e4ed7901SPeter Brune snes->norm_init_set = PETSC_FALSE; 1369184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 137089b92e6fSPeter Brune snes->gssweeps = 1; 13719b94acceSBarry Smith 1372c40d0f55SPeter Brune snes->pcside = PC_RIGHT; 1373c40d0f55SPeter Brune 1374d8f46077SPeter Brune snes->mf = PETSC_FALSE; 1375d8f46077SPeter Brune snes->mf_operator = PETSC_FALSE; 1376d8f46077SPeter Brune snes->mf_version = 1; 1377d8f46077SPeter Brune 13783d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 13793d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 13803d4c4710SBarry Smith 13819b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 138238f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 13839b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 13849b94acceSBarry Smith kctx->version = 2; 13859b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 13869b94acceSBarry Smith this was too large for some test cases */ 138775567043SBarry Smith kctx->rtol_last = 0.0; 13889b94acceSBarry Smith kctx->rtol_max = .9; 13899b94acceSBarry Smith kctx->gamma = 1.0; 139062d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 139171f87433Sdalcinl kctx->alpha2 = kctx->alpha; 13929b94acceSBarry Smith kctx->threshold = .1; 139375567043SBarry Smith kctx->lresid_last = 0.0; 139475567043SBarry Smith kctx->norm_last = 0.0; 13959b94acceSBarry Smith 13969b94acceSBarry Smith *outsnes = snes; 13973a40ed3dSBarry Smith PetscFunctionReturn(0); 13989b94acceSBarry Smith } 13999b94acceSBarry Smith 14004a2ae208SSatish Balay #undef __FUNCT__ 14014a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 14029b94acceSBarry Smith /*@C 14039b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 14049b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 14059b94acceSBarry Smith equations. 14069b94acceSBarry Smith 14073f9fe445SBarry Smith Logically Collective on SNES 1408fee21e36SBarry Smith 1409c7afd0dbSLois Curfman McInnes Input Parameters: 1410c7afd0dbSLois Curfman McInnes + snes - the SNES context 1411c7afd0dbSLois Curfman McInnes . r - vector to store function value 1412de044059SHong Zhang . func - function evaluation routine 1413c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1414c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 14159b94acceSBarry Smith 1416c7afd0dbSLois Curfman McInnes Calling sequence of func: 14178d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1418c7afd0dbSLois Curfman McInnes 1419c586c404SJed Brown + snes - the SNES context 1420c586c404SJed Brown . x - state at which to evaluate residual 1421c586c404SJed Brown . f - vector to put residual 1422c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 14239b94acceSBarry Smith 14249b94acceSBarry Smith Notes: 14259b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 14269b94acceSBarry Smith $ f'(x) x = -f(x), 1427c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 14289b94acceSBarry Smith 142936851e7fSLois Curfman McInnes Level: beginner 143036851e7fSLois Curfman McInnes 14319b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 14329b94acceSBarry Smith 14338b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard() 14349b94acceSBarry Smith @*/ 14357087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 14369b94acceSBarry Smith { 143785385478SLisandro Dalcin PetscErrorCode ierr; 14386cab3a1bSJed Brown DM dm; 14396cab3a1bSJed Brown 14403a40ed3dSBarry Smith PetscFunctionBegin; 14410700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1442d2a683ecSLisandro Dalcin if (r) { 1443d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1444d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 144585385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 14466bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 144785385478SLisandro Dalcin snes->vec_func = r; 1448d2a683ecSLisandro Dalcin } 14496cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 14506cab3a1bSJed Brown ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr); 14513a40ed3dSBarry Smith PetscFunctionReturn(0); 14529b94acceSBarry Smith } 14539b94acceSBarry Smith 1454646217ecSPeter Brune 1455646217ecSPeter Brune #undef __FUNCT__ 1456e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction" 1457e4ed7901SPeter Brune /*@C 1458e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1459e4ed7901SPeter Brune function norm at the initialization of the method. In some 1460e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1461e4ed7901SPeter Brune SNESSolve. This function allows one to avoid a redundant call 1462e4ed7901SPeter Brune to SNESComputeFunction in that case. 1463e4ed7901SPeter Brune 1464e4ed7901SPeter Brune Logically Collective on SNES 1465e4ed7901SPeter Brune 1466e4ed7901SPeter Brune Input Parameters: 1467e4ed7901SPeter Brune + snes - the SNES context 1468e4ed7901SPeter Brune - f - vector to store function value 1469e4ed7901SPeter Brune 1470e4ed7901SPeter Brune Notes: 1471e4ed7901SPeter Brune This should not be modified during the solution procedure. 1472e4ed7901SPeter Brune 1473e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1474e4ed7901SPeter Brune 1475e4ed7901SPeter Brune Level: developer 1476e4ed7901SPeter Brune 1477e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function 1478e4ed7901SPeter Brune 1479e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm() 1480e4ed7901SPeter Brune @*/ 1481e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1482e4ed7901SPeter Brune { 1483e4ed7901SPeter Brune PetscErrorCode ierr; 1484e4ed7901SPeter Brune Vec vec_func; 1485e4ed7901SPeter Brune 1486e4ed7901SPeter Brune PetscFunctionBegin; 1487e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1488e4ed7901SPeter Brune PetscValidHeaderSpecific(f,VEC_CLASSID,2); 1489e4ed7901SPeter Brune PetscCheckSameComm(snes,1,f,2); 1490e4ed7901SPeter Brune ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1491e4ed7901SPeter Brune ierr = VecCopy(f, vec_func);CHKERRQ(ierr); 1492217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 1493e4ed7901SPeter Brune PetscFunctionReturn(0); 1494e4ed7901SPeter Brune } 1495e4ed7901SPeter Brune 1496e4ed7901SPeter Brune 1497e4ed7901SPeter Brune #undef __FUNCT__ 1498e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm" 1499e4ed7901SPeter Brune /*@C 1500e4ed7901SPeter Brune SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm 1501e4ed7901SPeter Brune at the initialization of the method. In some instances, the user has precomputed 1502e4ed7901SPeter Brune the function and its norm before calling SNESSolve. This function allows one to 1503e4ed7901SPeter Brune avoid a redundant call to SNESComputeFunction() and VecNorm() in that case. 1504e4ed7901SPeter Brune 1505e4ed7901SPeter Brune Logically Collective on SNES 1506e4ed7901SPeter Brune 1507e4ed7901SPeter Brune Input Parameters: 1508e4ed7901SPeter Brune + snes - the SNES context 1509e4ed7901SPeter Brune - fnorm - the norm of F as set by SNESSetInitialFunction() 1510e4ed7901SPeter Brune 1511e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1512e4ed7901SPeter Brune 1513e4ed7901SPeter Brune Level: developer 1514e4ed7901SPeter Brune 1515e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm 1516e4ed7901SPeter Brune 1517e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction() 1518e4ed7901SPeter Brune @*/ 1519e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm) 1520e4ed7901SPeter Brune { 1521e4ed7901SPeter Brune PetscFunctionBegin; 1522e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1523e4ed7901SPeter Brune snes->norm_init = fnorm; 1524e4ed7901SPeter Brune snes->norm_init_set = PETSC_TRUE; 1525e4ed7901SPeter Brune PetscFunctionReturn(0); 1526e4ed7901SPeter Brune } 1527e4ed7901SPeter Brune 1528e4ed7901SPeter Brune #undef __FUNCT__ 1529534ebe21SPeter Brune #define __FUNCT__ "SNESSetNormType" 1530534ebe21SPeter Brune /*@ 1531534ebe21SPeter Brune SNESSetNormType - Sets the SNESNormType used in covergence and monitoring 1532534ebe21SPeter Brune of the SNES method. 1533534ebe21SPeter Brune 1534534ebe21SPeter Brune Logically Collective on SNES 1535534ebe21SPeter Brune 1536534ebe21SPeter Brune Input Parameters: 1537534ebe21SPeter Brune + snes - the SNES context 1538534ebe21SPeter Brune - normtype - the type of the norm used 1539534ebe21SPeter Brune 1540534ebe21SPeter Brune Notes: 1541534ebe21SPeter Brune Only certain SNES methods support certain SNESNormTypes. Most require evaluation 1542534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1543534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1544534ebe21SPeter Brune (SNESGS) and the like do not require the norm of the function to be computed, and therfore 1545534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1546534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1547534ebe21SPeter Brune their solution. 1548534ebe21SPeter Brune 1549534ebe21SPeter Brune Level: developer 1550534ebe21SPeter Brune 1551534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1552534ebe21SPeter Brune 1553534ebe21SPeter Brune .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType 1554534ebe21SPeter Brune @*/ 1555534ebe21SPeter Brune PetscErrorCode SNESSetNormType(SNES snes, SNESNormType normtype) 1556534ebe21SPeter Brune { 1557534ebe21SPeter Brune PetscFunctionBegin; 1558534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1559534ebe21SPeter Brune snes->normtype = normtype; 1560534ebe21SPeter Brune PetscFunctionReturn(0); 1561534ebe21SPeter Brune } 1562534ebe21SPeter Brune 1563534ebe21SPeter Brune 1564534ebe21SPeter Brune #undef __FUNCT__ 1565534ebe21SPeter Brune #define __FUNCT__ "SNESGetNormType" 1566534ebe21SPeter Brune /*@ 1567534ebe21SPeter Brune SNESGetNormType - Gets the SNESNormType used in covergence and monitoring 1568534ebe21SPeter Brune of the SNES method. 1569534ebe21SPeter Brune 1570534ebe21SPeter Brune Logically Collective on SNES 1571534ebe21SPeter Brune 1572534ebe21SPeter Brune Input Parameters: 1573534ebe21SPeter Brune + snes - the SNES context 1574534ebe21SPeter Brune - normtype - the type of the norm used 1575534ebe21SPeter Brune 1576534ebe21SPeter Brune Level: advanced 1577534ebe21SPeter Brune 1578534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1579534ebe21SPeter Brune 1580534ebe21SPeter Brune .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType 1581534ebe21SPeter Brune @*/ 1582534ebe21SPeter Brune PetscErrorCode SNESGetNormType(SNES snes, SNESNormType *normtype) 1583534ebe21SPeter Brune { 1584534ebe21SPeter Brune PetscFunctionBegin; 1585534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1586534ebe21SPeter Brune *normtype = snes->normtype; 1587534ebe21SPeter Brune PetscFunctionReturn(0); 1588534ebe21SPeter Brune } 1589534ebe21SPeter Brune 1590534ebe21SPeter Brune #undef __FUNCT__ 1591646217ecSPeter Brune #define __FUNCT__ "SNESSetGS" 1592c79ef259SPeter Brune /*@C 1593c79ef259SPeter Brune SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for 1594c79ef259SPeter Brune use with composed nonlinear solvers. 1595c79ef259SPeter Brune 1596c79ef259SPeter Brune Input Parameters: 1597c79ef259SPeter Brune + snes - the SNES context 1598c79ef259SPeter Brune . gsfunc - function evaluation routine 1599c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 1600c79ef259SPeter Brune smoother evaluation routine (may be PETSC_NULL) 1601c79ef259SPeter Brune 1602c79ef259SPeter Brune Calling sequence of func: 1603c79ef259SPeter Brune $ func (SNES snes,Vec x,Vec b,void *ctx); 1604c79ef259SPeter Brune 1605c79ef259SPeter Brune + X - solution vector 1606c79ef259SPeter Brune . B - RHS vector 1607d28543b3SPeter Brune - ctx - optional user-defined Gauss-Seidel context 1608c79ef259SPeter Brune 1609c79ef259SPeter Brune Notes: 1610c79ef259SPeter Brune The GS routines are used by the composed nonlinear solver to generate 1611c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1612c79ef259SPeter Brune 1613d28543b3SPeter Brune Level: intermediate 1614c79ef259SPeter Brune 1615d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1616c79ef259SPeter Brune 1617c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS() 1618c79ef259SPeter Brune @*/ 16196cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx) 16206cab3a1bSJed Brown { 16216cab3a1bSJed Brown PetscErrorCode ierr; 16226cab3a1bSJed Brown DM dm; 16236cab3a1bSJed Brown 1624646217ecSPeter Brune PetscFunctionBegin; 16256cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16266cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 16276cab3a1bSJed Brown ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr); 1628646217ecSPeter Brune PetscFunctionReturn(0); 1629646217ecSPeter Brune } 1630646217ecSPeter Brune 1631d25893d9SBarry Smith #undef __FUNCT__ 163289b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps" 163389b92e6fSPeter Brune /*@ 163489b92e6fSPeter Brune SNESSetGSSweeps - Sets the number of sweeps of GS to use. 163589b92e6fSPeter Brune 163689b92e6fSPeter Brune Input Parameters: 163789b92e6fSPeter Brune + snes - the SNES context 163889b92e6fSPeter Brune - sweeps - the number of sweeps of GS to perform. 163989b92e6fSPeter Brune 164089b92e6fSPeter Brune Level: intermediate 164189b92e6fSPeter Brune 164289b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 164389b92e6fSPeter Brune 164489b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps() 164589b92e6fSPeter Brune @*/ 164689b92e6fSPeter Brune 1647c35f09e5SBarry Smith PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) 1648c35f09e5SBarry Smith { 164989b92e6fSPeter Brune PetscFunctionBegin; 165089b92e6fSPeter Brune snes->gssweeps = sweeps; 165189b92e6fSPeter Brune PetscFunctionReturn(0); 165289b92e6fSPeter Brune } 165389b92e6fSPeter Brune 165489b92e6fSPeter Brune 165589b92e6fSPeter Brune #undef __FUNCT__ 165689b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps" 165789b92e6fSPeter Brune /*@ 165889b92e6fSPeter Brune SNESGetGSSweeps - Gets the number of sweeps GS will use. 165989b92e6fSPeter Brune 166089b92e6fSPeter Brune Input Parameters: 166189b92e6fSPeter Brune . snes - the SNES context 166289b92e6fSPeter Brune 166389b92e6fSPeter Brune Output Parameters: 166489b92e6fSPeter Brune . sweeps - the number of sweeps of GS to perform. 166589b92e6fSPeter Brune 166689b92e6fSPeter Brune Level: intermediate 166789b92e6fSPeter Brune 166889b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 166989b92e6fSPeter Brune 167089b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps() 167189b92e6fSPeter Brune @*/ 1672c35f09e5SBarry Smith PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) 1673c35f09e5SBarry Smith { 167489b92e6fSPeter Brune PetscFunctionBegin; 167589b92e6fSPeter Brune *sweeps = snes->gssweeps; 167689b92e6fSPeter Brune PetscFunctionReturn(0); 167789b92e6fSPeter Brune } 167889b92e6fSPeter Brune 167989b92e6fSPeter Brune #undef __FUNCT__ 16808b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 16818b0a5094SBarry Smith PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 16828b0a5094SBarry Smith { 16838b0a5094SBarry Smith PetscErrorCode ierr; 1684e03ab78fSPeter Brune DM dm; 1685e03ab78fSPeter Brune SNESDM sdm; 16866cab3a1bSJed Brown 16878b0a5094SBarry Smith PetscFunctionBegin; 1688e03ab78fSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1689e03ab78fSPeter Brune ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 16908b0a5094SBarry Smith /* A(x)*x - b(x) */ 1691e03ab78fSPeter Brune if (sdm->computepfunction) { 1692e03ab78fSPeter Brune ierr = (*sdm->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr); 1693e03ab78fSPeter Brune } else if (snes->dm) { 1694e03ab78fSPeter Brune ierr = DMComputeFunction(snes->dm,x,f);CHKERRQ(ierr); 1695e03ab78fSPeter Brune } else { 1696e03ab78fSPeter Brune SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() or SNESSetDM() before SNESPicardComputeFunction to provide Picard function."); 1697e03ab78fSPeter Brune } 1698e03ab78fSPeter Brune 1699e03ab78fSPeter Brune if (sdm->computepjacobian) { 1700e03ab78fSPeter Brune ierr = (*sdm->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,sdm->pctx);CHKERRQ(ierr); 1701e03ab78fSPeter Brune } else if (snes->dm) { 1702e03ab78fSPeter Brune ierr = DMComputeJacobian(snes->dm,x,snes->jacobian,snes->jacobian_pre,&snes->matstruct);CHKERRQ(ierr); 1703e03ab78fSPeter Brune } else { 1704e03ab78fSPeter Brune SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() or SNESSetDM() before SNESPicardComputeFunction to provide Picard matrix."); 1705e03ab78fSPeter Brune } 1706e03ab78fSPeter Brune 17078b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 17088b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 17098b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 17108b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 17118b0a5094SBarry Smith PetscFunctionReturn(0); 17128b0a5094SBarry Smith } 17138b0a5094SBarry Smith 17148b0a5094SBarry Smith #undef __FUNCT__ 17158b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 17168b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 17178b0a5094SBarry Smith { 17188b0a5094SBarry Smith PetscFunctionBegin; 1719e03ab78fSPeter Brune /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */ 17208b0a5094SBarry Smith *flag = snes->matstruct; 17218b0a5094SBarry Smith PetscFunctionReturn(0); 17228b0a5094SBarry Smith } 17238b0a5094SBarry Smith 17248b0a5094SBarry Smith #undef __FUNCT__ 17258b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 17268b0a5094SBarry Smith /*@C 17270d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 17288b0a5094SBarry Smith 17298b0a5094SBarry Smith Logically Collective on SNES 17308b0a5094SBarry Smith 17318b0a5094SBarry Smith Input Parameters: 17328b0a5094SBarry Smith + snes - the SNES context 17338b0a5094SBarry Smith . r - vector to store function value 17348b0a5094SBarry Smith . func - function evaluation routine 17358b0a5094SBarry 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) 17368b0a5094SBarry Smith . mat - matrix to store A 17378b0a5094SBarry Smith . mfunc - function to compute matrix value 17388b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 17398b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 17408b0a5094SBarry Smith 17418b0a5094SBarry Smith Calling sequence of func: 17428b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 17438b0a5094SBarry Smith 17448b0a5094SBarry Smith + f - function vector 17458b0a5094SBarry Smith - ctx - optional user-defined function context 17468b0a5094SBarry Smith 17478b0a5094SBarry Smith Calling sequence of mfunc: 17488b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 17498b0a5094SBarry Smith 17508b0a5094SBarry Smith + x - input vector 17518b0a5094SBarry 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(), 17528b0a5094SBarry Smith normally just pass mat in this location 17538b0a5094SBarry Smith . mat - form A(x) matrix 17548b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 17558b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 17568b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 17578b0a5094SBarry Smith 17588b0a5094SBarry Smith Notes: 17598b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 17608b0a5094SBarry Smith 17618b0a5094SBarry 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} 17628b0a5094SBarry 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. 17638b0a5094SBarry Smith 17648b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 17658b0a5094SBarry Smith 17660d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 17670d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 17688b0a5094SBarry Smith 17698b0a5094SBarry 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 17708b0a5094SBarry 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 17718b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 17728b0a5094SBarry Smith 17738b0a5094SBarry Smith Level: beginner 17748b0a5094SBarry Smith 17758b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 17768b0a5094SBarry Smith 17770d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard() 17788b0a5094SBarry Smith @*/ 17798b0a5094SBarry 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) 17808b0a5094SBarry Smith { 17818b0a5094SBarry Smith PetscErrorCode ierr; 1782e03ab78fSPeter Brune DM dm; 1783e03ab78fSPeter Brune 17848b0a5094SBarry Smith PetscFunctionBegin; 17858b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1786e03ab78fSPeter Brune ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 1787e03ab78fSPeter Brune ierr = DMSNESSetPicard(dm,func,mfunc,ctx);CHKERRQ(ierr); 17888b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 17898b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 17908b0a5094SBarry Smith PetscFunctionReturn(0); 17918b0a5094SBarry Smith } 17928b0a5094SBarry Smith 17937971a8bfSPeter Brune 17947971a8bfSPeter Brune #undef __FUNCT__ 17957971a8bfSPeter Brune #define __FUNCT__ "SNESGetPicard" 17967971a8bfSPeter Brune /*@C 17977971a8bfSPeter Brune SNESGetPicard - Returns the context for the Picard iteration 17987971a8bfSPeter Brune 17997971a8bfSPeter Brune Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 18007971a8bfSPeter Brune 18017971a8bfSPeter Brune Input Parameter: 18027971a8bfSPeter Brune . snes - the SNES context 18037971a8bfSPeter Brune 18047971a8bfSPeter Brune Output Parameter: 18057971a8bfSPeter Brune + r - the function (or PETSC_NULL) 18067971a8bfSPeter Brune . func - the function (or PETSC_NULL) 18077971a8bfSPeter Brune . jmat - the picard matrix (or PETSC_NULL) 18087971a8bfSPeter Brune . mat - the picard preconditioner matrix (or PETSC_NULL) 18097971a8bfSPeter Brune . mfunc - the function for matrix evaluation (or PETSC_NULL) 18107971a8bfSPeter Brune - ctx - the function context (or PETSC_NULL) 18117971a8bfSPeter Brune 18127971a8bfSPeter Brune Level: advanced 18137971a8bfSPeter Brune 18147971a8bfSPeter Brune .keywords: SNES, nonlinear, get, function 18157971a8bfSPeter Brune 18167971a8bfSPeter Brune .seealso: SNESSetPicard, SNESGetFunction, SNESGetJacobian, SNESGetDM 18177971a8bfSPeter Brune @*/ 18187971a8bfSPeter 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) 18197971a8bfSPeter Brune { 18207971a8bfSPeter Brune PetscErrorCode ierr; 18217971a8bfSPeter Brune DM dm; 18227971a8bfSPeter Brune 18237971a8bfSPeter Brune PetscFunctionBegin; 18247971a8bfSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 18257971a8bfSPeter Brune ierr = SNESGetFunction(snes,r,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 18267971a8bfSPeter Brune ierr = SNESGetJacobian(snes,jmat,mat,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 18277971a8bfSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18287971a8bfSPeter Brune ierr = DMSNESGetPicard(dm,func,mfunc,ctx);CHKERRQ(ierr); 18297971a8bfSPeter Brune PetscFunctionReturn(0); 18307971a8bfSPeter Brune } 18317971a8bfSPeter Brune 18328b0a5094SBarry Smith #undef __FUNCT__ 1833d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1834d25893d9SBarry Smith /*@C 1835d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1836d25893d9SBarry Smith 1837d25893d9SBarry Smith Logically Collective on SNES 1838d25893d9SBarry Smith 1839d25893d9SBarry Smith Input Parameters: 1840d25893d9SBarry Smith + snes - the SNES context 1841d25893d9SBarry Smith . func - function evaluation routine 1842d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1843d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1844d25893d9SBarry Smith 1845d25893d9SBarry Smith Calling sequence of func: 1846d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1847d25893d9SBarry Smith 1848d25893d9SBarry Smith . f - function vector 1849d25893d9SBarry Smith - ctx - optional user-defined function context 1850d25893d9SBarry Smith 1851d25893d9SBarry Smith Level: intermediate 1852d25893d9SBarry Smith 1853d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1854d25893d9SBarry Smith 1855d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1856d25893d9SBarry Smith @*/ 1857d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1858d25893d9SBarry Smith { 1859d25893d9SBarry Smith PetscFunctionBegin; 1860d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1861d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1862d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1863d25893d9SBarry Smith PetscFunctionReturn(0); 1864d25893d9SBarry Smith } 1865d25893d9SBarry Smith 18663ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 18673ab0aad5SBarry Smith #undef __FUNCT__ 18681096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 18691096aae1SMatthew Knepley /*@C 18701096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 18711096aae1SMatthew Knepley it assumes a zero right hand side. 18721096aae1SMatthew Knepley 18733f9fe445SBarry Smith Logically Collective on SNES 18741096aae1SMatthew Knepley 18751096aae1SMatthew Knepley Input Parameter: 18761096aae1SMatthew Knepley . snes - the SNES context 18771096aae1SMatthew Knepley 18781096aae1SMatthew Knepley Output Parameter: 1879bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 18801096aae1SMatthew Knepley 18811096aae1SMatthew Knepley Level: intermediate 18821096aae1SMatthew Knepley 18831096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 18841096aae1SMatthew Knepley 188585385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 18861096aae1SMatthew Knepley @*/ 18877087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 18881096aae1SMatthew Knepley { 18891096aae1SMatthew Knepley PetscFunctionBegin; 18900700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 18911096aae1SMatthew Knepley PetscValidPointer(rhs,2); 189285385478SLisandro Dalcin *rhs = snes->vec_rhs; 18931096aae1SMatthew Knepley PetscFunctionReturn(0); 18941096aae1SMatthew Knepley } 18951096aae1SMatthew Knepley 18961096aae1SMatthew Knepley #undef __FUNCT__ 18974a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 18989b94acceSBarry Smith /*@ 189936851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 19009b94acceSBarry Smith SNESSetFunction(). 19019b94acceSBarry Smith 1902c7afd0dbSLois Curfman McInnes Collective on SNES 1903c7afd0dbSLois Curfman McInnes 19049b94acceSBarry Smith Input Parameters: 1905c7afd0dbSLois Curfman McInnes + snes - the SNES context 1906c7afd0dbSLois Curfman McInnes - x - input vector 19079b94acceSBarry Smith 19089b94acceSBarry Smith Output Parameter: 19093638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 19109b94acceSBarry Smith 19111bffabb2SLois Curfman McInnes Notes: 191236851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 191336851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 191436851e7fSLois Curfman McInnes themselves. 191536851e7fSLois Curfman McInnes 191636851e7fSLois Curfman McInnes Level: developer 191736851e7fSLois Curfman McInnes 19189b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 19199b94acceSBarry Smith 1920a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 19219b94acceSBarry Smith @*/ 19227087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 19239b94acceSBarry Smith { 1924dfbe8321SBarry Smith PetscErrorCode ierr; 19256cab3a1bSJed Brown DM dm; 19266cab3a1bSJed Brown SNESDM sdm; 19279b94acceSBarry Smith 19283a40ed3dSBarry Smith PetscFunctionBegin; 19290700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 19300700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 19310700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1932c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1933c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 19344ec14c9cSBarry Smith VecValidValues(x,2,PETSC_TRUE); 1935184914b5SBarry Smith 19366cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 19376cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 1938d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 1939c40d0f55SPeter Brune if (snes->pc && snes->pcside == PC_LEFT) { 1940c40d0f55SPeter Brune ierr = VecCopy(x,y);CHKERRQ(ierr); 1941c40d0f55SPeter Brune ierr = SNESSolve(snes->pc,snes->vec_rhs,y);CHKERRQ(ierr); 1942c40d0f55SPeter Brune ierr = VecAYPX(y,-1.0,x);CHKERRQ(ierr); 1943c40d0f55SPeter Brune } else if (sdm->computefunction) { 1944d64ed03dSBarry Smith PetscStackPush("SNES user function"); 19456cab3a1bSJed Brown ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 1946d64ed03dSBarry Smith PetscStackPop; 194773250ac0SBarry Smith } else if (snes->dm) { 1948644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1949c90fad12SPeter Brune } else if (snes->vec_rhs) { 1950c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1951644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 195285385478SLisandro Dalcin if (snes->vec_rhs) { 195385385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 19543ab0aad5SBarry Smith } 1955ae3c334cSLois Curfman McInnes snes->nfuncs++; 1956d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 19574ec14c9cSBarry Smith VecValidValues(y,3,PETSC_FALSE); 19583a40ed3dSBarry Smith PetscFunctionReturn(0); 19599b94acceSBarry Smith } 19609b94acceSBarry Smith 19614a2ae208SSatish Balay #undef __FUNCT__ 1962646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1963c79ef259SPeter Brune /*@ 1964c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1965c79ef259SPeter Brune SNESSetGS(). 1966c79ef259SPeter Brune 1967c79ef259SPeter Brune Collective on SNES 1968c79ef259SPeter Brune 1969c79ef259SPeter Brune Input Parameters: 1970c79ef259SPeter Brune + snes - the SNES context 1971c79ef259SPeter Brune . x - input vector 1972c79ef259SPeter Brune - b - rhs vector 1973c79ef259SPeter Brune 1974c79ef259SPeter Brune Output Parameter: 1975c79ef259SPeter Brune . x - new solution vector 1976c79ef259SPeter Brune 1977c79ef259SPeter Brune Notes: 1978c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1979c79ef259SPeter Brune implementations, so most users would not generally call this routine 1980c79ef259SPeter Brune themselves. 1981c79ef259SPeter Brune 1982c79ef259SPeter Brune Level: developer 1983c79ef259SPeter Brune 1984c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1985c79ef259SPeter Brune 1986c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1987c79ef259SPeter Brune @*/ 1988646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1989646217ecSPeter Brune { 1990646217ecSPeter Brune PetscErrorCode ierr; 199189b92e6fSPeter Brune PetscInt i; 19926cab3a1bSJed Brown DM dm; 19936cab3a1bSJed Brown SNESDM sdm; 1994646217ecSPeter Brune 1995646217ecSPeter Brune PetscFunctionBegin; 1996646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1997646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1998646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1999646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 2000646217ecSPeter Brune if (b) PetscCheckSameComm(snes,1,b,3); 20014ec14c9cSBarry Smith if (b) VecValidValues(b,2,PETSC_TRUE); 2002701cf23dSPeter Brune ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 20036cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 20046cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 20056cab3a1bSJed Brown if (sdm->computegs) { 200689b92e6fSPeter Brune for (i = 0; i < snes->gssweeps; i++) { 2007646217ecSPeter Brune PetscStackPush("SNES user GS"); 20086cab3a1bSJed Brown ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 2009646217ecSPeter Brune PetscStackPop; 201089b92e6fSPeter Brune } 2011646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 2012701cf23dSPeter Brune ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 20134ec14c9cSBarry Smith VecValidValues(x,3,PETSC_FALSE); 2014646217ecSPeter Brune PetscFunctionReturn(0); 2015646217ecSPeter Brune } 2016646217ecSPeter Brune 2017646217ecSPeter Brune 2018646217ecSPeter Brune #undef __FUNCT__ 20194a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 202062fef451SLois Curfman McInnes /*@ 202162fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 202262fef451SLois Curfman McInnes set with SNESSetJacobian(). 202362fef451SLois Curfman McInnes 2024c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 2025c7afd0dbSLois Curfman McInnes 202662fef451SLois Curfman McInnes Input Parameters: 2027c7afd0dbSLois Curfman McInnes + snes - the SNES context 2028c7afd0dbSLois Curfman McInnes - x - input vector 202962fef451SLois Curfman McInnes 203062fef451SLois Curfman McInnes Output Parameters: 2031c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 203262fef451SLois Curfman McInnes . B - optional preconditioning matrix 20332b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 2034fee21e36SBarry Smith 2035e35cf81dSBarry Smith Options Database Keys: 2036e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 2037693365a8SJed Brown . -snes_lag_jacobian <lag> 2038693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 2039693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 2040693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 20414c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 2042c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 2043c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 2044c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 2045c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2046c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 20474c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 2048c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 2049c01495d3SJed Brown 2050e35cf81dSBarry Smith 205162fef451SLois Curfman McInnes Notes: 205262fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 205362fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 205462fef451SLois Curfman McInnes 205594b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 2056dc5a77f8SLois Curfman McInnes flag parameter. 205762fef451SLois Curfman McInnes 205836851e7fSLois Curfman McInnes Level: developer 205936851e7fSLois Curfman McInnes 206062fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 206162fef451SLois Curfman McInnes 2062e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 206362fef451SLois Curfman McInnes @*/ 20647087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 20659b94acceSBarry Smith { 2066dfbe8321SBarry Smith PetscErrorCode ierr; 2067ace3abfcSBarry Smith PetscBool flag; 20686cab3a1bSJed Brown DM dm; 20696cab3a1bSJed Brown SNESDM sdm; 20703a40ed3dSBarry Smith 20713a40ed3dSBarry Smith PetscFunctionBegin; 20720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 20730700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 20744482741eSBarry Smith PetscValidPointer(flg,5); 2075c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 20764ec14c9cSBarry Smith VecValidValues(X,2,PETSC_TRUE); 20776cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 20786cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 20793232da50SPeter Brune 20806cab3a1bSJed Brown if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 2081ebd3b9afSBarry Smith 2082ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 2083ebd3b9afSBarry Smith 2084fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 2085fe3ffe1eSBarry Smith snes->lagjacobian = -1; 2086fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 2087fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 2088e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 2089e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 2090251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 2091ebd3b9afSBarry Smith if (flag) { 2092ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2093ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2094ebd3b9afSBarry Smith } 2095e35cf81dSBarry Smith PetscFunctionReturn(0); 2096e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 2097e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 2098e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 2099251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 2100ebd3b9afSBarry Smith if (flag) { 2101ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2102ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2103ebd3b9afSBarry Smith } 2104e35cf81dSBarry Smith PetscFunctionReturn(0); 2105e35cf81dSBarry Smith } 2106e35cf81dSBarry Smith 2107c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 2108e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 21093232da50SPeter Brune 2110d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 21113232da50SPeter Brune if (snes->mf && !snes->mf_operator) { 21123232da50SPeter Brune ierr = MatMFFDComputeJacobian(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr); 21133232da50SPeter Brune } else { 21146cab3a1bSJed Brown ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr); 21153232da50SPeter Brune } 2116d64ed03dSBarry Smith PetscStackPop; 21173232da50SPeter Brune 2118d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 2119a8054027SBarry Smith 21203b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 21213b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 21223b4f5425SBarry Smith snes->lagpreconditioner = -1; 21233b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 2124a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 2125a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 2126a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 2127a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 2128a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 2129a8054027SBarry Smith } 2130a8054027SBarry Smith 21316d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 21320700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 21330700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 2134693365a8SJed Brown { 2135693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 2136693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 2137693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 2138693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 2139693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 2140693365a8SJed Brown if (flag || flag_draw || flag_contour) { 2141693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 2142693365a8SJed Brown MatStructure mstruct; 2143693365a8SJed Brown PetscViewer vdraw,vstdout; 21446b3a5b13SJed Brown PetscBool flg; 2145693365a8SJed Brown if (flag_operator) { 2146693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 2147693365a8SJed Brown Bexp = Bexp_mine; 2148693365a8SJed Brown } else { 2149693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 2150251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 2151693365a8SJed Brown if (flg) Bexp = *B; 2152693365a8SJed Brown else { 2153693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 2154693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 2155693365a8SJed Brown Bexp = Bexp_mine; 2156693365a8SJed Brown } 2157693365a8SJed Brown } 2158693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 2159693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 2160693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 2161693365a8SJed Brown if (flag_draw || flag_contour) { 2162693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2163693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 2164693365a8SJed Brown } else vdraw = PETSC_NULL; 2165693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 2166693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 2167693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 2168693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 2169693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2170693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 2171693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2172693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 2173693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2174693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 2175693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2176693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 2177693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2178693365a8SJed Brown } 2179693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2180693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2181693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 2182693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 2183693365a8SJed Brown } 2184693365a8SJed Brown } 21854c30e9fbSJed Brown { 21866719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 21876719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 21884c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 21896719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 21904c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 21914c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 21926719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 21936719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 21946719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 21956719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 21964c30e9fbSJed Brown Mat Bfd; 21974c30e9fbSJed Brown MatStructure mstruct; 21984c30e9fbSJed Brown PetscViewer vdraw,vstdout; 21994c30e9fbSJed Brown ISColoring iscoloring; 22004c30e9fbSJed Brown MatFDColoring matfdcoloring; 22014c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 22024c30e9fbSJed Brown void *funcctx; 22036719d8e4SJed Brown PetscReal norm1,norm2,normmax; 22044c30e9fbSJed Brown 22054c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 22064c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 22074c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 22084c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 22094c30e9fbSJed Brown 22104c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 22114c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 22124c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 22134c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 22144c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 22154c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 22164c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 22174c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 22184c30e9fbSJed Brown 22194c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 22204c30e9fbSJed Brown if (flag_draw || flag_contour) { 22214c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 22224c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 22234c30e9fbSJed Brown } else vdraw = PETSC_NULL; 22244c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 22256719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 22264c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 22274c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 22286719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 22294c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 22304c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 22314c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 22326719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 22334c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 22346719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 22356719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 22364c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 22374c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 22384c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 22394c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 22404c30e9fbSJed Brown } 22414c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 22426719d8e4SJed Brown 22436719d8e4SJed Brown if (flag_threshold) { 22446719d8e4SJed Brown PetscInt bs,rstart,rend,i; 22456719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 22466719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 22476719d8e4SJed Brown for (i=rstart; i<rend; i++) { 22486719d8e4SJed Brown const PetscScalar *ba,*ca; 22496719d8e4SJed Brown const PetscInt *bj,*cj; 22506719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 22516719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 22526719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 22536719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 22546719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 22556719d8e4SJed Brown for (j=0; j<bn; j++) { 22566719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 22576719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 22586719d8e4SJed Brown maxentrycol = bj[j]; 22596719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 22606719d8e4SJed Brown } 22616719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 22626719d8e4SJed Brown maxdiffcol = bj[j]; 22636719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 22646719d8e4SJed Brown } 22656719d8e4SJed Brown if (rdiff > maxrdiff) { 22666719d8e4SJed Brown maxrdiffcol = bj[j]; 22676719d8e4SJed Brown maxrdiff = rdiff; 22686719d8e4SJed Brown } 22696719d8e4SJed Brown } 22706719d8e4SJed Brown if (maxrdiff > 1) { 22716719d8e4SJed 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); 22726719d8e4SJed Brown for (j=0; j<bn; j++) { 22736719d8e4SJed Brown PetscReal rdiff; 22746719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 22756719d8e4SJed Brown if (rdiff > 1) { 22766719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 22776719d8e4SJed Brown } 22786719d8e4SJed Brown } 22796719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 22806719d8e4SJed Brown } 22816719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 22826719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 22836719d8e4SJed Brown } 22846719d8e4SJed Brown } 22854c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 22864c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 22874c30e9fbSJed Brown } 22884c30e9fbSJed Brown } 22893a40ed3dSBarry Smith PetscFunctionReturn(0); 22909b94acceSBarry Smith } 22919b94acceSBarry Smith 22924a2ae208SSatish Balay #undef __FUNCT__ 22934a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 22949b94acceSBarry Smith /*@C 22959b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2296044dda88SLois Curfman McInnes location to store the matrix. 22979b94acceSBarry Smith 22983f9fe445SBarry Smith Logically Collective on SNES and Mat 2299c7afd0dbSLois Curfman McInnes 23009b94acceSBarry Smith Input Parameters: 2301c7afd0dbSLois Curfman McInnes + snes - the SNES context 23029b94acceSBarry Smith . A - Jacobian matrix 23039b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 2304efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 2305c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 2306efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 23079b94acceSBarry Smith 23089b94acceSBarry Smith Calling sequence of func: 23098d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 23109b94acceSBarry Smith 2311c7afd0dbSLois Curfman McInnes + x - input vector 23129b94acceSBarry Smith . A - Jacobian matrix 23139b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 2314ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 23152b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 2316c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 23179b94acceSBarry Smith 23189b94acceSBarry Smith Notes: 231994b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 23202cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 2321ac21db08SLois Curfman McInnes 2322ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 23239b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 23249b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 23259b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 23269b94acceSBarry Smith throughout the global iterations. 23279b94acceSBarry Smith 232816913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 232916913363SBarry Smith each matrix. 233016913363SBarry Smith 2331a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 2332a8a26c1eSJed Brown must be a MatFDColoring. 2333a8a26c1eSJed Brown 2334c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2335c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2336c3cc8fd1SJed Brown 233736851e7fSLois Curfman McInnes Level: beginner 233836851e7fSLois Curfman McInnes 23399b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 23409b94acceSBarry Smith 23413ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 23429b94acceSBarry Smith @*/ 23437087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 23449b94acceSBarry Smith { 2345dfbe8321SBarry Smith PetscErrorCode ierr; 23466cab3a1bSJed Brown DM dm; 23473a7fca6bSBarry Smith 23483a40ed3dSBarry Smith PetscFunctionBegin; 23490700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23500700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 23510700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 2352c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 235306975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 23546cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 23556cab3a1bSJed Brown ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr); 23563a7fca6bSBarry Smith if (A) { 23577dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 23586bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 23599b94acceSBarry Smith snes->jacobian = A; 23603a7fca6bSBarry Smith } 23613a7fca6bSBarry Smith if (B) { 23627dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 23636bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 23649b94acceSBarry Smith snes->jacobian_pre = B; 23653a7fca6bSBarry Smith } 23663a40ed3dSBarry Smith PetscFunctionReturn(0); 23679b94acceSBarry Smith } 236862fef451SLois Curfman McInnes 23694a2ae208SSatish Balay #undef __FUNCT__ 23704a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 2371c2aafc4cSSatish Balay /*@C 2372b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2373b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2374b4fd4287SBarry Smith 2375c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2376c7afd0dbSLois Curfman McInnes 2377b4fd4287SBarry Smith Input Parameter: 2378b4fd4287SBarry Smith . snes - the nonlinear solver context 2379b4fd4287SBarry Smith 2380b4fd4287SBarry Smith Output Parameters: 2381c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 2382b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 238370e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 238470e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 2385fee21e36SBarry Smith 238636851e7fSLois Curfman McInnes Level: advanced 238736851e7fSLois Curfman McInnes 2388b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 2389b4fd4287SBarry Smith @*/ 23907087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 2391b4fd4287SBarry Smith { 23926cab3a1bSJed Brown PetscErrorCode ierr; 23936cab3a1bSJed Brown DM dm; 23946cab3a1bSJed Brown SNESDM sdm; 23956cab3a1bSJed Brown 23963a40ed3dSBarry Smith PetscFunctionBegin; 23970700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2398b4fd4287SBarry Smith if (A) *A = snes->jacobian; 2399b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 24006cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 24016cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 24026cab3a1bSJed Brown if (func) *func = sdm->computejacobian; 24036cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 24043a40ed3dSBarry Smith PetscFunctionReturn(0); 2405b4fd4287SBarry Smith } 2406b4fd4287SBarry Smith 24079b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 24089b94acceSBarry Smith 24094a2ae208SSatish Balay #undef __FUNCT__ 24104a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 24119b94acceSBarry Smith /*@ 24129b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2413272ac6f2SLois Curfman McInnes of a nonlinear solver. 24149b94acceSBarry Smith 2415fee21e36SBarry Smith Collective on SNES 2416fee21e36SBarry Smith 2417c7afd0dbSLois Curfman McInnes Input Parameters: 241870e92668SMatthew Knepley . snes - the SNES context 2419c7afd0dbSLois Curfman McInnes 2420272ac6f2SLois Curfman McInnes Notes: 2421272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2422272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2423272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2424272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2425272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2426272ac6f2SLois Curfman McInnes 242736851e7fSLois Curfman McInnes Level: advanced 242836851e7fSLois Curfman McInnes 24299b94acceSBarry Smith .keywords: SNES, nonlinear, setup 24309b94acceSBarry Smith 24319b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 24329b94acceSBarry Smith @*/ 24337087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 24349b94acceSBarry Smith { 2435dfbe8321SBarry Smith PetscErrorCode ierr; 24366cab3a1bSJed Brown DM dm; 24376cab3a1bSJed Brown SNESDM sdm; 2438c35f09e5SBarry Smith SNESLineSearch linesearch, pclinesearch; 24396e2a1849SPeter Brune void *lsprectx,*lspostctx; 24406e2a1849SPeter Brune SNESLineSearchPreCheckFunc lsprefunc; 24416e2a1849SPeter Brune SNESLineSearchPostCheckFunc lspostfunc; 24426e2a1849SPeter Brune PetscErrorCode (*func)(SNES,Vec,Vec,void*); 24436e2a1849SPeter Brune Vec f,fpc; 24446e2a1849SPeter Brune void *funcctx; 24456e2a1849SPeter Brune PetscErrorCode (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 24461eb13d49SPeter Brune void *jacctx,*appctx; 24476e2a1849SPeter Brune Mat A,B; 24483a40ed3dSBarry Smith 24493a40ed3dSBarry Smith PetscFunctionBegin; 24500700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 24514dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 24529b94acceSBarry Smith 24537adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 245485385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 245585385478SLisandro Dalcin } 245685385478SLisandro Dalcin 2457a63bb30eSJed Brown ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 245817186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 245958c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 246058c9b817SLisandro Dalcin 246158c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 246258c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 246358c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 246458c9b817SLisandro Dalcin } 246558c9b817SLisandro Dalcin 24666cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2467d8f46077SPeter Brune ierr = DMShellSetGlobalVector(snes->dm,snes->vec_sol);CHKERRQ(ierr); 24686cab3a1bSJed Brown ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */ 24696cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 24706cab3a1bSJed Brown if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc"); 24716cab3a1bSJed Brown if (!snes->vec_func) { 24726cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2473214df951SJed Brown } 2474efd51863SBarry Smith 2475b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 2476b710008aSBarry Smith 2477f1c6b773SPeter Brune if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);} 24789e764e56SPeter Brune 2479c40d0f55SPeter Brune if (snes->pc && (snes->pcside == PC_LEFT)) snes->mf = PETSC_TRUE; 2480d8f46077SPeter Brune 2481d8f46077SPeter Brune if (snes->mf) { ierr = SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);CHKERRQ(ierr); } 2482d8f46077SPeter Brune 2483d8f46077SPeter Brune 2484d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 2485d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2486d25893d9SBarry Smith } 2487d25893d9SBarry Smith 24886e2a1849SPeter Brune if (snes->pc) { 24896e2a1849SPeter Brune /* copy the DM over */ 24906e2a1849SPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 24916e2a1849SPeter Brune ierr = SNESSetDM(snes->pc,dm);CHKERRQ(ierr); 24926e2a1849SPeter Brune 24936e2a1849SPeter Brune /* copy the legacy SNES context not related to the DM over*/ 24946e2a1849SPeter Brune ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr); 24956e2a1849SPeter Brune ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr); 24966e2a1849SPeter Brune ierr = SNESSetFunction(snes->pc,fpc,func,funcctx);CHKERRQ(ierr); 24976e2a1849SPeter Brune ierr = SNESGetJacobian(snes,&A,&B,&jac,&jacctx);CHKERRQ(ierr); 24986e2a1849SPeter Brune ierr = SNESSetJacobian(snes->pc,A,B,jac,jacctx);CHKERRQ(ierr); 24991eb13d49SPeter Brune ierr = SNESGetApplicationContext(snes,&appctx);CHKERRQ(ierr); 25001eb13d49SPeter Brune ierr = SNESSetApplicationContext(snes->pc,appctx);CHKERRQ(ierr); 25016e2a1849SPeter Brune ierr = VecDestroy(&fpc);CHKERRQ(ierr); 25026e2a1849SPeter Brune 25036e2a1849SPeter Brune /* copy the function pointers over */ 25046e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr); 25056e2a1849SPeter Brune 25066e2a1849SPeter Brune /* default to 1 iteration */ 2507140836e4SPeter Brune ierr = SNESSetTolerances(snes->pc, 0.0, 0.0, 0.0, 1, snes->pc->max_funcs);CHKERRQ(ierr); 25086e2a1849SPeter Brune ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); 25096e2a1849SPeter Brune ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 25106e2a1849SPeter Brune 25116e2a1849SPeter Brune /* copy the line search context over */ 25126e2a1849SPeter Brune ierr = SNESGetSNESLineSearch(snes,&linesearch);CHKERRQ(ierr); 25136e2a1849SPeter Brune ierr = SNESGetSNESLineSearch(snes->pc,&pclinesearch);CHKERRQ(ierr); 25146e2a1849SPeter Brune ierr = SNESLineSearchGetPreCheck(linesearch,&lsprefunc,&lsprectx);CHKERRQ(ierr); 25156e2a1849SPeter Brune ierr = SNESLineSearchGetPostCheck(linesearch,&lspostfunc,&lspostctx);CHKERRQ(ierr); 25166e2a1849SPeter Brune ierr = SNESLineSearchSetPreCheck(pclinesearch,lsprefunc,lsprectx);CHKERRQ(ierr); 25176e2a1849SPeter Brune ierr = SNESLineSearchSetPostCheck(pclinesearch,lspostfunc,lspostctx);CHKERRQ(ierr); 25186e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr); 25196e2a1849SPeter Brune } 25206e2a1849SPeter Brune 2521410397dcSLisandro Dalcin if (snes->ops->setup) { 2522410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2523410397dcSLisandro Dalcin } 252458c9b817SLisandro Dalcin 25257aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 25263a40ed3dSBarry Smith PetscFunctionReturn(0); 25279b94acceSBarry Smith } 25289b94acceSBarry Smith 25294a2ae208SSatish Balay #undef __FUNCT__ 253037596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 253137596af1SLisandro Dalcin /*@ 253237596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 253337596af1SLisandro Dalcin 253437596af1SLisandro Dalcin Collective on SNES 253537596af1SLisandro Dalcin 253637596af1SLisandro Dalcin Input Parameter: 253737596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 253837596af1SLisandro Dalcin 2539d25893d9SBarry Smith Level: intermediate 2540d25893d9SBarry Smith 2541d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 254237596af1SLisandro Dalcin 254337596af1SLisandro Dalcin .keywords: SNES, destroy 254437596af1SLisandro Dalcin 254537596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 254637596af1SLisandro Dalcin @*/ 254737596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 254837596af1SLisandro Dalcin { 254937596af1SLisandro Dalcin PetscErrorCode ierr; 255037596af1SLisandro Dalcin 255137596af1SLisandro Dalcin PetscFunctionBegin; 255237596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2553d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2554d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2555d25893d9SBarry Smith snes->user = PETSC_NULL; 2556d25893d9SBarry Smith } 25578a23116dSBarry Smith if (snes->pc) { 25588a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 25598a23116dSBarry Smith } 25608a23116dSBarry Smith 256137596af1SLisandro Dalcin if (snes->ops->reset) { 256237596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 256337596af1SLisandro Dalcin } 25649e764e56SPeter Brune if (snes->ksp) { 25659e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 25669e764e56SPeter Brune } 25679e764e56SPeter Brune 25689e764e56SPeter Brune if (snes->linesearch) { 2569f1c6b773SPeter Brune ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 25709e764e56SPeter Brune } 25719e764e56SPeter Brune 25726bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 25736bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 25746bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 25756bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 25766bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 25776bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2578c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2579c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 258037596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 258137596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 258237596af1SLisandro Dalcin PetscFunctionReturn(0); 258337596af1SLisandro Dalcin } 258437596af1SLisandro Dalcin 258537596af1SLisandro Dalcin #undef __FUNCT__ 25864a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 258752baeb72SSatish Balay /*@ 25889b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 25899b94acceSBarry Smith with SNESCreate(). 25909b94acceSBarry Smith 2591c7afd0dbSLois Curfman McInnes Collective on SNES 2592c7afd0dbSLois Curfman McInnes 25939b94acceSBarry Smith Input Parameter: 25949b94acceSBarry Smith . snes - the SNES context 25959b94acceSBarry Smith 259636851e7fSLois Curfman McInnes Level: beginner 259736851e7fSLois Curfman McInnes 25989b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 25999b94acceSBarry Smith 260063a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 26019b94acceSBarry Smith @*/ 26026bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 26039b94acceSBarry Smith { 26046849ba73SBarry Smith PetscErrorCode ierr; 26053a40ed3dSBarry Smith 26063a40ed3dSBarry Smith PetscFunctionBegin; 26076bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 26086bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 26096bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2610d4bb536fSBarry Smith 26116bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 26128a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 26136b8b9a38SLisandro Dalcin 2614be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 26156bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 26166bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 26176d4c513bSLisandro Dalcin 26186bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 26196bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 2620f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 26216b8b9a38SLisandro Dalcin 26226bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 26236bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 26246bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 26256b8b9a38SLisandro Dalcin } 26266bf464f9SBarry Smith if ((*snes)->conv_malloc) { 26276bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 26286bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 262958c9b817SLisandro Dalcin } 26306bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2631a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 26323a40ed3dSBarry Smith PetscFunctionReturn(0); 26339b94acceSBarry Smith } 26349b94acceSBarry Smith 26359b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 26369b94acceSBarry Smith 26374a2ae208SSatish Balay #undef __FUNCT__ 2638a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2639a8054027SBarry Smith /*@ 2640a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2641a8054027SBarry Smith 26423f9fe445SBarry Smith Logically Collective on SNES 2643a8054027SBarry Smith 2644a8054027SBarry Smith Input Parameters: 2645a8054027SBarry Smith + snes - the SNES context 2646a8054027SBarry 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 26473b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2648a8054027SBarry Smith 2649a8054027SBarry Smith Options Database Keys: 2650a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2651a8054027SBarry Smith 2652a8054027SBarry Smith Notes: 2653a8054027SBarry Smith The default is 1 2654a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2655a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2656a8054027SBarry Smith 2657a8054027SBarry Smith Level: intermediate 2658a8054027SBarry Smith 2659a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2660a8054027SBarry Smith 2661e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2662a8054027SBarry Smith 2663a8054027SBarry Smith @*/ 26647087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2665a8054027SBarry Smith { 2666a8054027SBarry Smith PetscFunctionBegin; 26670700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2668e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2669e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2670c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2671a8054027SBarry Smith snes->lagpreconditioner = lag; 2672a8054027SBarry Smith PetscFunctionReturn(0); 2673a8054027SBarry Smith } 2674a8054027SBarry Smith 2675a8054027SBarry Smith #undef __FUNCT__ 2676efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2677efd51863SBarry Smith /*@ 2678efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2679efd51863SBarry Smith 2680efd51863SBarry Smith Logically Collective on SNES 2681efd51863SBarry Smith 2682efd51863SBarry Smith Input Parameters: 2683efd51863SBarry Smith + snes - the SNES context 2684efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2685efd51863SBarry Smith 2686efd51863SBarry Smith Options Database Keys: 2687efd51863SBarry Smith . -snes_grid_sequence <steps> 2688efd51863SBarry Smith 2689efd51863SBarry Smith Level: intermediate 2690efd51863SBarry Smith 2691c0df2a02SJed Brown Notes: 2692c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2693c0df2a02SJed Brown 2694efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2695efd51863SBarry Smith 2696efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2697efd51863SBarry Smith 2698efd51863SBarry Smith @*/ 2699efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2700efd51863SBarry Smith { 2701efd51863SBarry Smith PetscFunctionBegin; 2702efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2703efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2704efd51863SBarry Smith snes->gridsequence = steps; 2705efd51863SBarry Smith PetscFunctionReturn(0); 2706efd51863SBarry Smith } 2707efd51863SBarry Smith 2708efd51863SBarry Smith #undef __FUNCT__ 2709a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2710a8054027SBarry Smith /*@ 2711a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2712a8054027SBarry Smith 27133f9fe445SBarry Smith Not Collective 2714a8054027SBarry Smith 2715a8054027SBarry Smith Input Parameter: 2716a8054027SBarry Smith . snes - the SNES context 2717a8054027SBarry Smith 2718a8054027SBarry Smith Output Parameter: 2719a8054027SBarry 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 27203b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2721a8054027SBarry Smith 2722a8054027SBarry Smith Options Database Keys: 2723a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2724a8054027SBarry Smith 2725a8054027SBarry Smith Notes: 2726a8054027SBarry Smith The default is 1 2727a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2728a8054027SBarry Smith 2729a8054027SBarry Smith Level: intermediate 2730a8054027SBarry Smith 2731a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2732a8054027SBarry Smith 2733a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2734a8054027SBarry Smith 2735a8054027SBarry Smith @*/ 27367087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2737a8054027SBarry Smith { 2738a8054027SBarry Smith PetscFunctionBegin; 27390700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2740a8054027SBarry Smith *lag = snes->lagpreconditioner; 2741a8054027SBarry Smith PetscFunctionReturn(0); 2742a8054027SBarry Smith } 2743a8054027SBarry Smith 2744a8054027SBarry Smith #undef __FUNCT__ 2745e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2746e35cf81dSBarry Smith /*@ 2747e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2748e35cf81dSBarry Smith often the preconditioner is rebuilt. 2749e35cf81dSBarry Smith 27503f9fe445SBarry Smith Logically Collective on SNES 2751e35cf81dSBarry Smith 2752e35cf81dSBarry Smith Input Parameters: 2753e35cf81dSBarry Smith + snes - the SNES context 2754e35cf81dSBarry 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 2755fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2756e35cf81dSBarry Smith 2757e35cf81dSBarry Smith Options Database Keys: 2758e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2759e35cf81dSBarry Smith 2760e35cf81dSBarry Smith Notes: 2761e35cf81dSBarry Smith The default is 1 2762e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2763fe3ffe1eSBarry 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 2764fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2765e35cf81dSBarry Smith 2766e35cf81dSBarry Smith Level: intermediate 2767e35cf81dSBarry Smith 2768e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2769e35cf81dSBarry Smith 2770e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2771e35cf81dSBarry Smith 2772e35cf81dSBarry Smith @*/ 27737087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2774e35cf81dSBarry Smith { 2775e35cf81dSBarry Smith PetscFunctionBegin; 27760700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2777e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2778e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2779c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2780e35cf81dSBarry Smith snes->lagjacobian = lag; 2781e35cf81dSBarry Smith PetscFunctionReturn(0); 2782e35cf81dSBarry Smith } 2783e35cf81dSBarry Smith 2784e35cf81dSBarry Smith #undef __FUNCT__ 2785e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2786e35cf81dSBarry Smith /*@ 2787e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2788e35cf81dSBarry Smith 27893f9fe445SBarry Smith Not Collective 2790e35cf81dSBarry Smith 2791e35cf81dSBarry Smith Input Parameter: 2792e35cf81dSBarry Smith . snes - the SNES context 2793e35cf81dSBarry Smith 2794e35cf81dSBarry Smith Output Parameter: 2795e35cf81dSBarry 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 2796e35cf81dSBarry Smith the Jacobian is built etc. 2797e35cf81dSBarry Smith 2798e35cf81dSBarry Smith Options Database Keys: 2799e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2800e35cf81dSBarry Smith 2801e35cf81dSBarry Smith Notes: 2802e35cf81dSBarry Smith The default is 1 2803e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2804e35cf81dSBarry Smith 2805e35cf81dSBarry Smith Level: intermediate 2806e35cf81dSBarry Smith 2807e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2808e35cf81dSBarry Smith 2809e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2810e35cf81dSBarry Smith 2811e35cf81dSBarry Smith @*/ 28127087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2813e35cf81dSBarry Smith { 2814e35cf81dSBarry Smith PetscFunctionBegin; 28150700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2816e35cf81dSBarry Smith *lag = snes->lagjacobian; 2817e35cf81dSBarry Smith PetscFunctionReturn(0); 2818e35cf81dSBarry Smith } 2819e35cf81dSBarry Smith 2820e35cf81dSBarry Smith #undef __FUNCT__ 28214a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 28229b94acceSBarry Smith /*@ 2823d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 28249b94acceSBarry Smith 28253f9fe445SBarry Smith Logically Collective on SNES 2826c7afd0dbSLois Curfman McInnes 28279b94acceSBarry Smith Input Parameters: 2828c7afd0dbSLois Curfman McInnes + snes - the SNES context 282970441072SBarry Smith . abstol - absolute convergence tolerance 283033174efeSLois Curfman McInnes . rtol - relative convergence tolerance 283133174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 283233174efeSLois Curfman McInnes of the change in the solution between steps 283333174efeSLois Curfman McInnes . maxit - maximum number of iterations 2834c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2835fee21e36SBarry Smith 283633174efeSLois Curfman McInnes Options Database Keys: 283770441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2838c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2839c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2840c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2841c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 28429b94acceSBarry Smith 2843d7a720efSLois Curfman McInnes Notes: 28449b94acceSBarry Smith The default maximum number of iterations is 50. 28459b94acceSBarry Smith The default maximum number of function evaluations is 1000. 28469b94acceSBarry Smith 284736851e7fSLois Curfman McInnes Level: intermediate 284836851e7fSLois Curfman McInnes 284933174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 28509b94acceSBarry Smith 28512492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 28529b94acceSBarry Smith @*/ 28537087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 28549b94acceSBarry Smith { 28553a40ed3dSBarry Smith PetscFunctionBegin; 28560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2857c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2858c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2859c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2860c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2861c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2862c5eb9154SBarry Smith 2863ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2864ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2865ab54825eSJed Brown snes->abstol = abstol; 2866ab54825eSJed Brown } 2867ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2868ab54825eSJed 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); 2869ab54825eSJed Brown snes->rtol = rtol; 2870ab54825eSJed Brown } 2871ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2872ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2873c60f73f4SPeter Brune snes->stol = stol; 2874ab54825eSJed Brown } 2875ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2876ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2877ab54825eSJed Brown snes->max_its = maxit; 2878ab54825eSJed Brown } 2879ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2880ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2881ab54825eSJed Brown snes->max_funcs = maxf; 2882ab54825eSJed Brown } 288388976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 28843a40ed3dSBarry Smith PetscFunctionReturn(0); 28859b94acceSBarry Smith } 28869b94acceSBarry Smith 28874a2ae208SSatish Balay #undef __FUNCT__ 28884a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 28899b94acceSBarry Smith /*@ 289033174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 289133174efeSLois Curfman McInnes 2892c7afd0dbSLois Curfman McInnes Not Collective 2893c7afd0dbSLois Curfman McInnes 289433174efeSLois Curfman McInnes Input Parameters: 2895c7afd0dbSLois Curfman McInnes + snes - the SNES context 289685385478SLisandro Dalcin . atol - absolute convergence tolerance 289733174efeSLois Curfman McInnes . rtol - relative convergence tolerance 289833174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 289933174efeSLois Curfman McInnes of the change in the solution between steps 290033174efeSLois Curfman McInnes . maxit - maximum number of iterations 2901c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2902fee21e36SBarry Smith 290333174efeSLois Curfman McInnes Notes: 290433174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 290533174efeSLois Curfman McInnes 290636851e7fSLois Curfman McInnes Level: intermediate 290736851e7fSLois Curfman McInnes 290833174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 290933174efeSLois Curfman McInnes 291033174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 291133174efeSLois Curfman McInnes @*/ 29127087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 291333174efeSLois Curfman McInnes { 29143a40ed3dSBarry Smith PetscFunctionBegin; 29150700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 291685385478SLisandro Dalcin if (atol) *atol = snes->abstol; 291733174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 2918c60f73f4SPeter Brune if (stol) *stol = snes->stol; 291933174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 292033174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 29213a40ed3dSBarry Smith PetscFunctionReturn(0); 292233174efeSLois Curfman McInnes } 292333174efeSLois Curfman McInnes 29244a2ae208SSatish Balay #undef __FUNCT__ 29254a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 292633174efeSLois Curfman McInnes /*@ 29279b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 29289b94acceSBarry Smith 29293f9fe445SBarry Smith Logically Collective on SNES 2930fee21e36SBarry Smith 2931c7afd0dbSLois Curfman McInnes Input Parameters: 2932c7afd0dbSLois Curfman McInnes + snes - the SNES context 2933c7afd0dbSLois Curfman McInnes - tol - tolerance 2934c7afd0dbSLois Curfman McInnes 29359b94acceSBarry Smith Options Database Key: 2936c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 29379b94acceSBarry Smith 293836851e7fSLois Curfman McInnes Level: intermediate 293936851e7fSLois Curfman McInnes 29409b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 29419b94acceSBarry Smith 29422492ecdbSBarry Smith .seealso: SNESSetTolerances() 29439b94acceSBarry Smith @*/ 29447087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 29459b94acceSBarry Smith { 29463a40ed3dSBarry Smith PetscFunctionBegin; 29470700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2948c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 29499b94acceSBarry Smith snes->deltatol = tol; 29503a40ed3dSBarry Smith PetscFunctionReturn(0); 29519b94acceSBarry Smith } 29529b94acceSBarry Smith 2953df9fa365SBarry Smith /* 2954df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2955df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2956df9fa365SBarry Smith macros instead of functions 2957df9fa365SBarry Smith */ 29584a2ae208SSatish Balay #undef __FUNCT__ 29594619e776SBarry Smith #define __FUNCT__ "SNESMonitorLGResidualNorm" 29604619e776SBarry Smith PetscErrorCode SNESMonitorLGResidualNorm(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2961ce1608b8SBarry Smith { 2962dfbe8321SBarry Smith PetscErrorCode ierr; 2963ce1608b8SBarry Smith 2964ce1608b8SBarry Smith PetscFunctionBegin; 29650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 29661d1e9da1SBarry Smith ierr = KSPMonitorLGResidualNorm((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2967ce1608b8SBarry Smith PetscFunctionReturn(0); 2968ce1608b8SBarry Smith } 2969ce1608b8SBarry Smith 29704a2ae208SSatish Balay #undef __FUNCT__ 2971a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 29727087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2973df9fa365SBarry Smith { 2974dfbe8321SBarry Smith PetscErrorCode ierr; 2975df9fa365SBarry Smith 2976df9fa365SBarry Smith PetscFunctionBegin; 29771d1e9da1SBarry Smith ierr = KSPMonitorLGResidualNormCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2978df9fa365SBarry Smith PetscFunctionReturn(0); 2979df9fa365SBarry Smith } 2980df9fa365SBarry Smith 29814a2ae208SSatish Balay #undef __FUNCT__ 2982a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 29836bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2984df9fa365SBarry Smith { 2985dfbe8321SBarry Smith PetscErrorCode ierr; 2986df9fa365SBarry Smith 2987df9fa365SBarry Smith PetscFunctionBegin; 29881d1e9da1SBarry Smith ierr = KSPMonitorLGResidualNormDestroy(draw);CHKERRQ(ierr); 2989df9fa365SBarry Smith PetscFunctionReturn(0); 2990df9fa365SBarry Smith } 2991df9fa365SBarry Smith 29927087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2993b271bb04SBarry Smith #undef __FUNCT__ 2994b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 29957087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2996b271bb04SBarry Smith { 2997b271bb04SBarry Smith PetscDrawLG lg; 2998b271bb04SBarry Smith PetscErrorCode ierr; 2999b271bb04SBarry Smith PetscReal x,y,per; 3000b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 3001b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 3002b271bb04SBarry Smith PetscDraw draw; 3003b271bb04SBarry Smith 3004459f5d12SBarry Smith PetscFunctionBegin; 3005b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 3006b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3007b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3008b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 3009b271bb04SBarry Smith x = (PetscReal) n; 3010b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 3011b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3012b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 3013b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 3014b271bb04SBarry Smith } 3015b271bb04SBarry Smith 3016b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 3017b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3018b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3019b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 3020b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 3021b271bb04SBarry Smith x = (PetscReal) n; 3022b271bb04SBarry Smith y = 100.0*per; 3023b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3024b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 3025b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 3026b271bb04SBarry Smith } 3027b271bb04SBarry Smith 3028b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 3029b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3030b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3031b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 3032b271bb04SBarry Smith x = (PetscReal) n; 3033b271bb04SBarry Smith y = (prev - rnorm)/prev; 3034b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3035b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 3036b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 3037b271bb04SBarry Smith } 3038b271bb04SBarry Smith 3039b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 3040b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3041b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3042b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 3043b271bb04SBarry Smith x = (PetscReal) n; 3044b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 3045b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 3046b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3047b271bb04SBarry Smith } 3048b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 3049b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 3050b271bb04SBarry Smith } 3051b271bb04SBarry Smith prev = rnorm; 3052b271bb04SBarry Smith PetscFunctionReturn(0); 3053b271bb04SBarry Smith } 3054b271bb04SBarry Smith 3055b271bb04SBarry Smith #undef __FUNCT__ 30567a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 3057228d79bcSJed Brown /*@ 3058228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 3059228d79bcSJed Brown 3060228d79bcSJed Brown Collective on SNES 3061228d79bcSJed Brown 3062228d79bcSJed Brown Input Parameters: 3063228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 3064228d79bcSJed Brown . iter - iteration number 3065228d79bcSJed Brown - rnorm - relative norm of the residual 3066228d79bcSJed Brown 3067228d79bcSJed Brown Notes: 3068228d79bcSJed Brown This routine is called by the SNES implementations. 3069228d79bcSJed Brown It does not typically need to be called by the user. 3070228d79bcSJed Brown 3071228d79bcSJed Brown Level: developer 3072228d79bcSJed Brown 3073228d79bcSJed Brown .seealso: SNESMonitorSet() 3074228d79bcSJed Brown @*/ 30757a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 30767a03ce2fSLisandro Dalcin { 30777a03ce2fSLisandro Dalcin PetscErrorCode ierr; 30787a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 30797a03ce2fSLisandro Dalcin 30807a03ce2fSLisandro Dalcin PetscFunctionBegin; 30817a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 30827a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 30837a03ce2fSLisandro Dalcin } 30847a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 30857a03ce2fSLisandro Dalcin } 30867a03ce2fSLisandro Dalcin 30879b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 30889b94acceSBarry Smith 30894a2ae208SSatish Balay #undef __FUNCT__ 3090a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 30919b94acceSBarry Smith /*@C 3092a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 30939b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 30949b94acceSBarry Smith progress. 30959b94acceSBarry Smith 30963f9fe445SBarry Smith Logically Collective on SNES 3097fee21e36SBarry Smith 3098c7afd0dbSLois Curfman McInnes Input Parameters: 3099c7afd0dbSLois Curfman McInnes + snes - the SNES context 3100c7afd0dbSLois Curfman McInnes . func - monitoring routine 3101b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 3102e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 3103b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 3104b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 31059b94acceSBarry Smith 3106c7afd0dbSLois Curfman McInnes Calling sequence of func: 3107a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 3108c7afd0dbSLois Curfman McInnes 3109c7afd0dbSLois Curfman McInnes + snes - the SNES context 3110c7afd0dbSLois Curfman McInnes . its - iteration number 3111c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 311240a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 31139b94acceSBarry Smith 31149665c990SLois Curfman McInnes Options Database Keys: 3115a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 31164619e776SBarry Smith . -snes_monitor_lg_residualnorm - sets line graph monitor, 3117a6570f20SBarry Smith uses SNESMonitorLGCreate() 3118cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 3119c7afd0dbSLois Curfman McInnes been hardwired into a code by 3120a6570f20SBarry Smith calls to SNESMonitorSet(), but 3121c7afd0dbSLois Curfman McInnes does not cancel those set via 3122c7afd0dbSLois Curfman McInnes the options database. 31239665c990SLois Curfman McInnes 3124639f9d9dSBarry Smith Notes: 31256bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 3126a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 31276bc08f3fSLois Curfman McInnes order in which they were set. 3128639f9d9dSBarry Smith 3129025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 3130025f1a04SBarry Smith 313136851e7fSLois Curfman McInnes Level: intermediate 313236851e7fSLois Curfman McInnes 31339b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 31349b94acceSBarry Smith 3135a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 31369b94acceSBarry Smith @*/ 3137c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 31389b94acceSBarry Smith { 3139b90d0a6eSBarry Smith PetscInt i; 3140649052a6SBarry Smith PetscErrorCode ierr; 3141b90d0a6eSBarry Smith 31423a40ed3dSBarry Smith PetscFunctionBegin; 31430700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 314417186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 3145b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 3146649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 3147649052a6SBarry Smith if (monitordestroy) { 3148c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 3149649052a6SBarry Smith } 3150b90d0a6eSBarry Smith PetscFunctionReturn(0); 3151b90d0a6eSBarry Smith } 3152b90d0a6eSBarry Smith } 3153b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 3154b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 3155639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 31563a40ed3dSBarry Smith PetscFunctionReturn(0); 31579b94acceSBarry Smith } 31589b94acceSBarry Smith 31594a2ae208SSatish Balay #undef __FUNCT__ 3160a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 31615cd90555SBarry Smith /*@C 3162a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 31635cd90555SBarry Smith 31643f9fe445SBarry Smith Logically Collective on SNES 3165c7afd0dbSLois Curfman McInnes 31665cd90555SBarry Smith Input Parameters: 31675cd90555SBarry Smith . snes - the SNES context 31685cd90555SBarry Smith 31691a480d89SAdministrator Options Database Key: 3170a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 3171a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 3172c7afd0dbSLois Curfman McInnes set via the options database 31735cd90555SBarry Smith 31745cd90555SBarry Smith Notes: 31755cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 31765cd90555SBarry Smith 317736851e7fSLois Curfman McInnes Level: intermediate 317836851e7fSLois Curfman McInnes 31795cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 31805cd90555SBarry Smith 3181a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 31825cd90555SBarry Smith @*/ 31837087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 31845cd90555SBarry Smith { 3185d952e501SBarry Smith PetscErrorCode ierr; 3186d952e501SBarry Smith PetscInt i; 3187d952e501SBarry Smith 31885cd90555SBarry Smith PetscFunctionBegin; 31890700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3190d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 3191d952e501SBarry Smith if (snes->monitordestroy[i]) { 31923c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 3193d952e501SBarry Smith } 3194d952e501SBarry Smith } 31955cd90555SBarry Smith snes->numbermonitors = 0; 31965cd90555SBarry Smith PetscFunctionReturn(0); 31975cd90555SBarry Smith } 31985cd90555SBarry Smith 31994a2ae208SSatish Balay #undef __FUNCT__ 32004a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 32019b94acceSBarry Smith /*@C 32029b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 32039b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 32049b94acceSBarry Smith 32053f9fe445SBarry Smith Logically Collective on SNES 3206fee21e36SBarry Smith 3207c7afd0dbSLois Curfman McInnes Input Parameters: 3208c7afd0dbSLois Curfman McInnes + snes - the SNES context 3209c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 32107f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 32117f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 32129b94acceSBarry Smith 3213c7afd0dbSLois Curfman McInnes Calling sequence of func: 321406ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 3215c7afd0dbSLois Curfman McInnes 3216c7afd0dbSLois Curfman McInnes + snes - the SNES context 321706ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 3218c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 3219184914b5SBarry Smith . reason - reason for convergence/divergence 3220c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 32214b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 32224b27c08aSLois Curfman McInnes - f - 2-norm of function 32239b94acceSBarry Smith 322436851e7fSLois Curfman McInnes Level: advanced 322536851e7fSLois Curfman McInnes 32269b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 32279b94acceSBarry Smith 322885385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 32299b94acceSBarry Smith @*/ 32307087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 32319b94acceSBarry Smith { 32327f7931b9SBarry Smith PetscErrorCode ierr; 32337f7931b9SBarry Smith 32343a40ed3dSBarry Smith PetscFunctionBegin; 32350700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 323685385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 32377f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 32387f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 32397f7931b9SBarry Smith } 324085385478SLisandro Dalcin snes->ops->converged = func; 32417f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 324285385478SLisandro Dalcin snes->cnvP = cctx; 32433a40ed3dSBarry Smith PetscFunctionReturn(0); 32449b94acceSBarry Smith } 32459b94acceSBarry Smith 32464a2ae208SSatish Balay #undef __FUNCT__ 32474a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 324852baeb72SSatish Balay /*@ 3249184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 3250184914b5SBarry Smith 3251184914b5SBarry Smith Not Collective 3252184914b5SBarry Smith 3253184914b5SBarry Smith Input Parameter: 3254184914b5SBarry Smith . snes - the SNES context 3255184914b5SBarry Smith 3256184914b5SBarry Smith Output Parameter: 32574d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 3258184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 3259184914b5SBarry Smith 3260184914b5SBarry Smith Level: intermediate 3261184914b5SBarry Smith 3262184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 3263184914b5SBarry Smith 3264184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 3265184914b5SBarry Smith 326685385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 3267184914b5SBarry Smith @*/ 32687087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 3269184914b5SBarry Smith { 3270184914b5SBarry Smith PetscFunctionBegin; 32710700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 32724482741eSBarry Smith PetscValidPointer(reason,2); 3273184914b5SBarry Smith *reason = snes->reason; 3274184914b5SBarry Smith PetscFunctionReturn(0); 3275184914b5SBarry Smith } 3276184914b5SBarry Smith 32774a2ae208SSatish Balay #undef __FUNCT__ 32784a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 3279c9005455SLois Curfman McInnes /*@ 3280c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 3281c9005455SLois Curfman McInnes 32823f9fe445SBarry Smith Logically Collective on SNES 3283fee21e36SBarry Smith 3284c7afd0dbSLois Curfman McInnes Input Parameters: 3285c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 32868c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 3287cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 3288758f92a0SBarry Smith . na - size of a and its 328964731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 3290758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 3291c7afd0dbSLois Curfman McInnes 3292308dcc3eSBarry Smith Notes: 3293308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 3294308dcc3eSBarry Smith default array of length 10000 is allocated. 3295308dcc3eSBarry Smith 3296c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 3297c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 3298c9005455SLois Curfman McInnes during the section of code that is being timed. 3299c9005455SLois Curfman McInnes 330036851e7fSLois Curfman McInnes Level: intermediate 330136851e7fSLois Curfman McInnes 3302c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 3303758f92a0SBarry Smith 330408405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 3305758f92a0SBarry Smith 3306c9005455SLois Curfman McInnes @*/ 33077087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 3308c9005455SLois Curfman McInnes { 3309308dcc3eSBarry Smith PetscErrorCode ierr; 3310308dcc3eSBarry Smith 33113a40ed3dSBarry Smith PetscFunctionBegin; 33120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 33134482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 3314a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 3315308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 3316308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 3317308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 3318308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 3319308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 3320308dcc3eSBarry Smith } 3321c9005455SLois Curfman McInnes snes->conv_hist = a; 3322758f92a0SBarry Smith snes->conv_hist_its = its; 3323758f92a0SBarry Smith snes->conv_hist_max = na; 3324a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 3325758f92a0SBarry Smith snes->conv_hist_reset = reset; 3326758f92a0SBarry Smith PetscFunctionReturn(0); 3327758f92a0SBarry Smith } 3328758f92a0SBarry Smith 3329308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3330c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 3331c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 3332308dcc3eSBarry Smith EXTERN_C_BEGIN 3333308dcc3eSBarry Smith #undef __FUNCT__ 3334308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 3335308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3336308dcc3eSBarry Smith { 3337308dcc3eSBarry Smith mxArray *mat; 3338308dcc3eSBarry Smith PetscInt i; 3339308dcc3eSBarry Smith PetscReal *ar; 3340308dcc3eSBarry Smith 3341308dcc3eSBarry Smith PetscFunctionBegin; 3342308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3343308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3344308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 3345308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 3346308dcc3eSBarry Smith } 3347308dcc3eSBarry Smith PetscFunctionReturn(mat); 3348308dcc3eSBarry Smith } 3349308dcc3eSBarry Smith EXTERN_C_END 3350308dcc3eSBarry Smith #endif 3351308dcc3eSBarry Smith 3352308dcc3eSBarry Smith 33534a2ae208SSatish Balay #undef __FUNCT__ 33544a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 33550c4c9dddSBarry Smith /*@C 3356758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3357758f92a0SBarry Smith 33583f9fe445SBarry Smith Not Collective 3359758f92a0SBarry Smith 3360758f92a0SBarry Smith Input Parameter: 3361758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3362758f92a0SBarry Smith 3363758f92a0SBarry Smith Output Parameters: 3364758f92a0SBarry Smith . a - array to hold history 3365758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3366758f92a0SBarry Smith negative if not converged) for each solve. 3367758f92a0SBarry Smith - na - size of a and its 3368758f92a0SBarry Smith 3369758f92a0SBarry Smith Notes: 3370758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3371758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3372758f92a0SBarry Smith 3373758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3374758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3375758f92a0SBarry Smith during the section of code that is being timed. 3376758f92a0SBarry Smith 3377758f92a0SBarry Smith Level: intermediate 3378758f92a0SBarry Smith 3379758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3380758f92a0SBarry Smith 3381758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3382758f92a0SBarry Smith 3383758f92a0SBarry Smith @*/ 33847087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3385758f92a0SBarry Smith { 3386758f92a0SBarry Smith PetscFunctionBegin; 33870700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3388758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3389758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3390758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 33913a40ed3dSBarry Smith PetscFunctionReturn(0); 3392c9005455SLois Curfman McInnes } 3393c9005455SLois Curfman McInnes 3394e74ef692SMatthew Knepley #undef __FUNCT__ 3395e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 3396ac226902SBarry Smith /*@C 339776b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3398eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 33997e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 340076b2cf59SMatthew Knepley 34013f9fe445SBarry Smith Logically Collective on SNES 340276b2cf59SMatthew Knepley 340376b2cf59SMatthew Knepley Input Parameters: 340476b2cf59SMatthew Knepley . snes - The nonlinear solver context 340576b2cf59SMatthew Knepley . func - The function 340676b2cf59SMatthew Knepley 340776b2cf59SMatthew Knepley Calling sequence of func: 3408b5d30489SBarry Smith . func (SNES snes, PetscInt step); 340976b2cf59SMatthew Knepley 341076b2cf59SMatthew Knepley . step - The current step of the iteration 341176b2cf59SMatthew Knepley 3412fe97e370SBarry Smith Level: advanced 3413fe97e370SBarry Smith 3414fe97e370SBarry 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() 3415fe97e370SBarry Smith This is not used by most users. 341676b2cf59SMatthew Knepley 341776b2cf59SMatthew Knepley .keywords: SNES, update 3418b5d30489SBarry Smith 341985385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 342076b2cf59SMatthew Knepley @*/ 34217087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 342276b2cf59SMatthew Knepley { 342376b2cf59SMatthew Knepley PetscFunctionBegin; 34240700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3425e7788613SBarry Smith snes->ops->update = func; 342676b2cf59SMatthew Knepley PetscFunctionReturn(0); 342776b2cf59SMatthew Knepley } 342876b2cf59SMatthew Knepley 3429e74ef692SMatthew Knepley #undef __FUNCT__ 3430e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 343176b2cf59SMatthew Knepley /*@ 343276b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 343376b2cf59SMatthew Knepley 343476b2cf59SMatthew Knepley Not collective 343576b2cf59SMatthew Knepley 343676b2cf59SMatthew Knepley Input Parameters: 343776b2cf59SMatthew Knepley . snes - The nonlinear solver context 343876b2cf59SMatthew Knepley . step - The current step of the iteration 343976b2cf59SMatthew Knepley 3440205452f4SMatthew Knepley Level: intermediate 3441205452f4SMatthew Knepley 344276b2cf59SMatthew Knepley .keywords: SNES, update 3443a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 344476b2cf59SMatthew Knepley @*/ 34457087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 344676b2cf59SMatthew Knepley { 344776b2cf59SMatthew Knepley PetscFunctionBegin; 344876b2cf59SMatthew Knepley PetscFunctionReturn(0); 344976b2cf59SMatthew Knepley } 345076b2cf59SMatthew Knepley 34514a2ae208SSatish Balay #undef __FUNCT__ 34524a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 34539b94acceSBarry Smith /* 34549b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 34559b94acceSBarry Smith positive parameter delta. 34569b94acceSBarry Smith 34579b94acceSBarry Smith Input Parameters: 3458c7afd0dbSLois Curfman McInnes + snes - the SNES context 34599b94acceSBarry Smith . y - approximate solution of linear system 34609b94acceSBarry Smith . fnorm - 2-norm of current function 3461c7afd0dbSLois Curfman McInnes - delta - trust region size 34629b94acceSBarry Smith 34639b94acceSBarry Smith Output Parameters: 3464c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 34659b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 34669b94acceSBarry Smith region, and exceeds zero otherwise. 3467c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 34689b94acceSBarry Smith 34699b94acceSBarry Smith Note: 34704b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 34719b94acceSBarry Smith is set to be the maximum allowable step size. 34729b94acceSBarry Smith 34739b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 34749b94acceSBarry Smith */ 3475dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 34769b94acceSBarry Smith { 3477064f8208SBarry Smith PetscReal nrm; 3478ea709b57SSatish Balay PetscScalar cnorm; 3479dfbe8321SBarry Smith PetscErrorCode ierr; 34803a40ed3dSBarry Smith 34813a40ed3dSBarry Smith PetscFunctionBegin; 34820700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34830700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3484c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3485184914b5SBarry Smith 3486064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3487064f8208SBarry Smith if (nrm > *delta) { 3488064f8208SBarry Smith nrm = *delta/nrm; 3489064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3490064f8208SBarry Smith cnorm = nrm; 34912dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 34929b94acceSBarry Smith *ynorm = *delta; 34939b94acceSBarry Smith } else { 34949b94acceSBarry Smith *gpnorm = 0.0; 3495064f8208SBarry Smith *ynorm = nrm; 34969b94acceSBarry Smith } 34973a40ed3dSBarry Smith PetscFunctionReturn(0); 34989b94acceSBarry Smith } 34999b94acceSBarry Smith 35004a2ae208SSatish Balay #undef __FUNCT__ 35014a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 35026ce558aeSBarry Smith /*@C 3503f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3504f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 35059b94acceSBarry Smith 3506c7afd0dbSLois Curfman McInnes Collective on SNES 3507c7afd0dbSLois Curfman McInnes 3508b2002411SLois Curfman McInnes Input Parameters: 3509c7afd0dbSLois Curfman McInnes + snes - the SNES context 35103cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 351185385478SLisandro Dalcin - x - the solution vector. 35129b94acceSBarry Smith 3513b2002411SLois Curfman McInnes Notes: 35148ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 35158ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 35168ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 35178ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 35188ddd3da0SLois Curfman McInnes 351936851e7fSLois Curfman McInnes Level: beginner 352036851e7fSLois Curfman McInnes 35219b94acceSBarry Smith .keywords: SNES, nonlinear, solve 35229b94acceSBarry Smith 3523c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 35249b94acceSBarry Smith @*/ 35257087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 35269b94acceSBarry Smith { 3527dfbe8321SBarry Smith PetscErrorCode ierr; 3528ace3abfcSBarry Smith PetscBool flg; 3529eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 3530eabae89aSBarry Smith PetscViewer viewer; 3531efd51863SBarry Smith PetscInt grid; 3532a69afd8bSBarry Smith Vec xcreated = PETSC_NULL; 3533caa4e7f2SJed Brown DM dm; 3534052efed2SBarry Smith 35353a40ed3dSBarry Smith PetscFunctionBegin; 35360700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3537a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3538a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 35390700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 354085385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 354185385478SLisandro Dalcin 3542caa4e7f2SJed Brown if (!x) { 3543caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3544caa4e7f2SJed Brown ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 3545a69afd8bSBarry Smith x = xcreated; 3546a69afd8bSBarry Smith } 3547a69afd8bSBarry Smith 3548a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3549efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3550efd51863SBarry Smith 355185385478SLisandro Dalcin /* set solution vector */ 3552efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 35536bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 355485385478SLisandro Dalcin snes->vec_sol = x; 3555caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3556caa4e7f2SJed Brown 3557caa4e7f2SJed Brown /* set affine vector if provided */ 355885385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 35596bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 356085385478SLisandro Dalcin snes->vec_rhs = b; 356185385478SLisandro Dalcin 356270e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 35633f149594SLisandro Dalcin 35647eee914bSBarry Smith if (!grid) { 35657eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3566d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3567dd568438SSatish Balay } else if (snes->dm) { 3568dd568438SSatish Balay PetscBool ig; 3569dd568438SSatish Balay ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr); 3570dd568438SSatish Balay if (ig) { 35717eee914bSBarry Smith ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr); 35727eee914bSBarry Smith } 3573d25893d9SBarry Smith } 3574dd568438SSatish Balay } 3575d25893d9SBarry Smith 3576abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 357750ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3578d5e45103SBarry Smith 35793f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 35804936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 358185385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 35824936397dSBarry Smith if (snes->domainerror){ 35834936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 35844936397dSBarry Smith snes->domainerror = PETSC_FALSE; 35854936397dSBarry Smith } 358617186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 35873f149594SLisandro Dalcin 358890d69ab7SBarry Smith flg = PETSC_FALSE; 3589acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3590da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 35915968eb51SBarry Smith if (snes->printreason) { 3592a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 35935968eb51SBarry Smith if (snes->reason > 0) { 3594c7e7b494SJed 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); 35955968eb51SBarry Smith } else { 3596c7e7b494SJed 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); 35975968eb51SBarry Smith } 3598a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 35995968eb51SBarry Smith } 36005968eb51SBarry Smith 3601e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3602efd51863SBarry Smith if (grid < snes->gridsequence) { 3603efd51863SBarry Smith DM fine; 3604efd51863SBarry Smith Vec xnew; 3605efd51863SBarry Smith Mat interp; 3606efd51863SBarry Smith 3607efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3608c5c77316SJed Brown if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 3609e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3610efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3611efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3612c833c3b5SJed Brown ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr); 3613efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3614efd51863SBarry Smith x = xnew; 3615efd51863SBarry Smith 3616efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3617efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3618efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3619a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3620efd51863SBarry Smith } 3621efd51863SBarry Smith } 36223f7e2da0SPeter Brune /* monitoring and viewing */ 36233f7e2da0SPeter Brune flg = PETSC_FALSE; 36243f7e2da0SPeter Brune ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 36253f7e2da0SPeter Brune if (flg && !PetscPreLoadingOn) { 36263f7e2da0SPeter Brune ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 36273f7e2da0SPeter Brune ierr = SNESView(snes,viewer);CHKERRQ(ierr); 36283f7e2da0SPeter Brune ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 36293f7e2da0SPeter Brune } 36303f7e2da0SPeter Brune 36313f7e2da0SPeter Brune flg = PETSC_FALSE; 36323f7e2da0SPeter Brune ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 36333f7e2da0SPeter Brune if (flg) { 36343f7e2da0SPeter Brune PetscViewer viewer; 36353f7e2da0SPeter Brune ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 36363f7e2da0SPeter Brune ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 36373f7e2da0SPeter Brune ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 36383f7e2da0SPeter Brune ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 36393f7e2da0SPeter Brune ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 36403f7e2da0SPeter Brune } 36413f7e2da0SPeter Brune 3642a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 36433a40ed3dSBarry Smith PetscFunctionReturn(0); 36449b94acceSBarry Smith } 36459b94acceSBarry Smith 36469b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 36479b94acceSBarry Smith 36484a2ae208SSatish Balay #undef __FUNCT__ 36494a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 365082bf6240SBarry Smith /*@C 36514b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 36529b94acceSBarry Smith 3653fee21e36SBarry Smith Collective on SNES 3654fee21e36SBarry Smith 3655c7afd0dbSLois Curfman McInnes Input Parameters: 3656c7afd0dbSLois Curfman McInnes + snes - the SNES context 3657454a90a3SBarry Smith - type - a known method 3658c7afd0dbSLois Curfman McInnes 3659c7afd0dbSLois Curfman McInnes Options Database Key: 3660454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3661c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3662ae12b187SLois Curfman McInnes 36639b94acceSBarry Smith Notes: 3664e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 36654b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3666c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 36674b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3668c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 36699b94acceSBarry Smith 3670ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3671ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3672ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3673ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3674ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3675ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3676ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3677ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3678ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3679b0a32e0cSBarry Smith appropriate method. 368036851e7fSLois Curfman McInnes 368136851e7fSLois Curfman McInnes Level: intermediate 3682a703fe33SLois Curfman McInnes 3683454a90a3SBarry Smith .keywords: SNES, set, type 3684435da068SBarry Smith 3685435da068SBarry Smith .seealso: SNESType, SNESCreate() 3686435da068SBarry Smith 36879b94acceSBarry Smith @*/ 368819fd82e9SBarry Smith PetscErrorCode SNESSetType(SNES snes,SNESType type) 36899b94acceSBarry Smith { 3690dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3691ace3abfcSBarry Smith PetscBool match; 36923a40ed3dSBarry Smith 36933a40ed3dSBarry Smith PetscFunctionBegin; 36940700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36954482741eSBarry Smith PetscValidCharPointer(type,2); 369682bf6240SBarry Smith 3697251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 36980f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 369992ff6ae8SBarry Smith 37004b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3701e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 370275396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 3703b5c23020SJed Brown if (snes->ops->destroy) { 3704b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 3705b5c23020SJed Brown snes->ops->destroy = PETSC_NULL; 3706b5c23020SJed Brown } 370775396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 370875396ef9SLisandro Dalcin snes->ops->setup = 0; 370975396ef9SLisandro Dalcin snes->ops->solve = 0; 371075396ef9SLisandro Dalcin snes->ops->view = 0; 371175396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 371275396ef9SLisandro Dalcin snes->ops->destroy = 0; 371375396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 371475396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3715454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 371603bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 37179fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 37189fb22e1aSBarry Smith if (PetscAMSPublishAll) { 37199fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 37209fb22e1aSBarry Smith } 37219fb22e1aSBarry Smith #endif 37223a40ed3dSBarry Smith PetscFunctionReturn(0); 37239b94acceSBarry Smith } 37249b94acceSBarry Smith 3725a847f771SSatish Balay 37269b94acceSBarry Smith /* --------------------------------------------------------------------- */ 37274a2ae208SSatish Balay #undef __FUNCT__ 37284a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 372952baeb72SSatish Balay /*@ 37309b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3731f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 37329b94acceSBarry Smith 3733fee21e36SBarry Smith Not Collective 3734fee21e36SBarry Smith 373536851e7fSLois Curfman McInnes Level: advanced 373636851e7fSLois Curfman McInnes 37379b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 37389b94acceSBarry Smith 37399b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 37409b94acceSBarry Smith @*/ 37417087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 37429b94acceSBarry Smith { 3743dfbe8321SBarry Smith PetscErrorCode ierr; 374482bf6240SBarry Smith 37453a40ed3dSBarry Smith PetscFunctionBegin; 37461441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 37474c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 37483a40ed3dSBarry Smith PetscFunctionReturn(0); 37499b94acceSBarry Smith } 37509b94acceSBarry Smith 37514a2ae208SSatish Balay #undef __FUNCT__ 37524a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 37539b94acceSBarry Smith /*@C 37549a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 37559b94acceSBarry Smith 3756c7afd0dbSLois Curfman McInnes Not Collective 3757c7afd0dbSLois Curfman McInnes 37589b94acceSBarry Smith Input Parameter: 37594b0e389bSBarry Smith . snes - nonlinear solver context 37609b94acceSBarry Smith 37619b94acceSBarry Smith Output Parameter: 37623a7fca6bSBarry Smith . type - SNES method (a character string) 37639b94acceSBarry Smith 376436851e7fSLois Curfman McInnes Level: intermediate 376536851e7fSLois Curfman McInnes 3766454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 37679b94acceSBarry Smith @*/ 376819fd82e9SBarry Smith PetscErrorCode SNESGetType(SNES snes,SNESType *type) 37699b94acceSBarry Smith { 37703a40ed3dSBarry Smith PetscFunctionBegin; 37710700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37724482741eSBarry Smith PetscValidPointer(type,2); 37737adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 37743a40ed3dSBarry Smith PetscFunctionReturn(0); 37759b94acceSBarry Smith } 37769b94acceSBarry Smith 37774a2ae208SSatish Balay #undef __FUNCT__ 37784a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 377952baeb72SSatish Balay /*@ 37809b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3781c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 37829b94acceSBarry Smith 3783c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3784c7afd0dbSLois Curfman McInnes 37859b94acceSBarry Smith Input Parameter: 37869b94acceSBarry Smith . snes - the SNES context 37879b94acceSBarry Smith 37889b94acceSBarry Smith Output Parameter: 37899b94acceSBarry Smith . x - the solution 37909b94acceSBarry Smith 379170e92668SMatthew Knepley Level: intermediate 379236851e7fSLois Curfman McInnes 37939b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 37949b94acceSBarry Smith 379585385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 37969b94acceSBarry Smith @*/ 37977087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 37989b94acceSBarry Smith { 37993a40ed3dSBarry Smith PetscFunctionBegin; 38000700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 38014482741eSBarry Smith PetscValidPointer(x,2); 380285385478SLisandro Dalcin *x = snes->vec_sol; 380370e92668SMatthew Knepley PetscFunctionReturn(0); 380470e92668SMatthew Knepley } 380570e92668SMatthew Knepley 380670e92668SMatthew Knepley #undef __FUNCT__ 38074a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 380852baeb72SSatish Balay /*@ 38099b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 38109b94acceSBarry Smith stored. 38119b94acceSBarry Smith 3812c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3813c7afd0dbSLois Curfman McInnes 38149b94acceSBarry Smith Input Parameter: 38159b94acceSBarry Smith . snes - the SNES context 38169b94acceSBarry Smith 38179b94acceSBarry Smith Output Parameter: 38189b94acceSBarry Smith . x - the solution update 38199b94acceSBarry Smith 382036851e7fSLois Curfman McInnes Level: advanced 382136851e7fSLois Curfman McInnes 38229b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 38239b94acceSBarry Smith 382485385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 38259b94acceSBarry Smith @*/ 38267087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 38279b94acceSBarry Smith { 38283a40ed3dSBarry Smith PetscFunctionBegin; 38290700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 38304482741eSBarry Smith PetscValidPointer(x,2); 383185385478SLisandro Dalcin *x = snes->vec_sol_update; 38323a40ed3dSBarry Smith PetscFunctionReturn(0); 38339b94acceSBarry Smith } 38349b94acceSBarry Smith 38354a2ae208SSatish Balay #undef __FUNCT__ 38364a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 38379b94acceSBarry Smith /*@C 38383638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 38399b94acceSBarry Smith 3840a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 3841c7afd0dbSLois Curfman McInnes 38429b94acceSBarry Smith Input Parameter: 38439b94acceSBarry Smith . snes - the SNES context 38449b94acceSBarry Smith 38459b94acceSBarry Smith Output Parameter: 38467bf4e008SBarry Smith + r - the function (or PETSC_NULL) 384770e92668SMatthew Knepley . func - the function (or PETSC_NULL) 384870e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 38499b94acceSBarry Smith 385036851e7fSLois Curfman McInnes Level: advanced 385136851e7fSLois Curfman McInnes 3852a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 38539b94acceSBarry Smith 38544b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 38559b94acceSBarry Smith @*/ 38567087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 38579b94acceSBarry Smith { 3858a63bb30eSJed Brown PetscErrorCode ierr; 38596cab3a1bSJed Brown DM dm; 3860a63bb30eSJed Brown 38613a40ed3dSBarry Smith PetscFunctionBegin; 38620700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3863a63bb30eSJed Brown if (r) { 3864a63bb30eSJed Brown if (!snes->vec_func) { 3865a63bb30eSJed Brown if (snes->vec_rhs) { 3866a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 3867a63bb30eSJed Brown } else if (snes->vec_sol) { 3868a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 3869a63bb30eSJed Brown } else if (snes->dm) { 3870a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 3871a63bb30eSJed Brown } 3872a63bb30eSJed Brown } 3873a63bb30eSJed Brown *r = snes->vec_func; 3874a63bb30eSJed Brown } 38756cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 38766cab3a1bSJed Brown ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr); 38773a40ed3dSBarry Smith PetscFunctionReturn(0); 38789b94acceSBarry Smith } 38799b94acceSBarry Smith 3880c79ef259SPeter Brune /*@C 3881c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3882c79ef259SPeter Brune 3883c79ef259SPeter Brune Input Parameter: 3884c79ef259SPeter Brune . snes - the SNES context 3885c79ef259SPeter Brune 3886c79ef259SPeter Brune Output Parameter: 3887c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3888c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3889c79ef259SPeter Brune 3890c79ef259SPeter Brune Level: advanced 3891c79ef259SPeter Brune 3892c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3893c79ef259SPeter Brune 3894c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3895c79ef259SPeter Brune @*/ 3896c79ef259SPeter Brune 38974a2ae208SSatish Balay #undef __FUNCT__ 3898646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3899646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3900646217ecSPeter Brune { 39016cab3a1bSJed Brown PetscErrorCode ierr; 39026cab3a1bSJed Brown DM dm; 39036cab3a1bSJed Brown 3904646217ecSPeter Brune PetscFunctionBegin; 3905646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 39066cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 39076cab3a1bSJed Brown ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr); 3908646217ecSPeter Brune PetscFunctionReturn(0); 3909646217ecSPeter Brune } 3910646217ecSPeter Brune 39114a2ae208SSatish Balay #undef __FUNCT__ 39124a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 39133c7409f5SSatish Balay /*@C 39143c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3915d850072dSLois Curfman McInnes SNES options in the database. 39163c7409f5SSatish Balay 39173f9fe445SBarry Smith Logically Collective on SNES 3918fee21e36SBarry Smith 3919c7afd0dbSLois Curfman McInnes Input Parameter: 3920c7afd0dbSLois Curfman McInnes + snes - the SNES context 3921c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3922c7afd0dbSLois Curfman McInnes 3923d850072dSLois Curfman McInnes Notes: 3924a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3925c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3926d850072dSLois Curfman McInnes 392736851e7fSLois Curfman McInnes Level: advanced 392836851e7fSLois Curfman McInnes 39293c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3930a86d99e1SLois Curfman McInnes 3931a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 39323c7409f5SSatish Balay @*/ 39337087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 39343c7409f5SSatish Balay { 3935dfbe8321SBarry Smith PetscErrorCode ierr; 39363c7409f5SSatish Balay 39373a40ed3dSBarry Smith PetscFunctionBegin; 39380700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3939639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 39401cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 394135f5d045SPeter Brune if (snes->linesearch) { 394235f5d045SPeter Brune ierr = SNESGetSNESLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 394308b6c495SPeter Brune ierr = PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 394435f5d045SPeter Brune } 394535f5d045SPeter Brune ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 39463a40ed3dSBarry Smith PetscFunctionReturn(0); 39473c7409f5SSatish Balay } 39483c7409f5SSatish Balay 39494a2ae208SSatish Balay #undef __FUNCT__ 39504a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 39513c7409f5SSatish Balay /*@C 3952f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3953d850072dSLois Curfman McInnes SNES options in the database. 39543c7409f5SSatish Balay 39553f9fe445SBarry Smith Logically Collective on SNES 3956fee21e36SBarry Smith 3957c7afd0dbSLois Curfman McInnes Input Parameters: 3958c7afd0dbSLois Curfman McInnes + snes - the SNES context 3959c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3960c7afd0dbSLois Curfman McInnes 3961d850072dSLois Curfman McInnes Notes: 3962a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3963c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3964d850072dSLois Curfman McInnes 396536851e7fSLois Curfman McInnes Level: advanced 396636851e7fSLois Curfman McInnes 39673c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3968a86d99e1SLois Curfman McInnes 3969a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 39703c7409f5SSatish Balay @*/ 39717087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 39723c7409f5SSatish Balay { 3973dfbe8321SBarry Smith PetscErrorCode ierr; 39743c7409f5SSatish Balay 39753a40ed3dSBarry Smith PetscFunctionBegin; 39760700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3977639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 39781cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 397935f5d045SPeter Brune if (snes->linesearch) { 398035f5d045SPeter Brune ierr = SNESGetSNESLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 398108b6c495SPeter Brune ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 398235f5d045SPeter Brune } 398335f5d045SPeter Brune ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 39843a40ed3dSBarry Smith PetscFunctionReturn(0); 39853c7409f5SSatish Balay } 39863c7409f5SSatish Balay 39874a2ae208SSatish Balay #undef __FUNCT__ 39884a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 39899ab63eb5SSatish Balay /*@C 39903c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 39913c7409f5SSatish Balay SNES options in the database. 39923c7409f5SSatish Balay 3993c7afd0dbSLois Curfman McInnes Not Collective 3994c7afd0dbSLois Curfman McInnes 39953c7409f5SSatish Balay Input Parameter: 39963c7409f5SSatish Balay . snes - the SNES context 39973c7409f5SSatish Balay 39983c7409f5SSatish Balay Output Parameter: 39993c7409f5SSatish Balay . prefix - pointer to the prefix string used 40003c7409f5SSatish Balay 40014ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 40029ab63eb5SSatish Balay sufficient length to hold the prefix. 40039ab63eb5SSatish Balay 400436851e7fSLois Curfman McInnes Level: advanced 400536851e7fSLois Curfman McInnes 40063c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 4007a86d99e1SLois Curfman McInnes 4008a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 40093c7409f5SSatish Balay @*/ 40107087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 40113c7409f5SSatish Balay { 4012dfbe8321SBarry Smith PetscErrorCode ierr; 40133c7409f5SSatish Balay 40143a40ed3dSBarry Smith PetscFunctionBegin; 40150700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4016639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 40173a40ed3dSBarry Smith PetscFunctionReturn(0); 40183c7409f5SSatish Balay } 40193c7409f5SSatish Balay 4020b2002411SLois Curfman McInnes 40214a2ae208SSatish Balay #undef __FUNCT__ 40224a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 40233cea93caSBarry Smith /*@C 40243cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 40253cea93caSBarry Smith 40267f6c08e0SMatthew Knepley Level: advanced 40273cea93caSBarry Smith @*/ 40287087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 4029b2002411SLois Curfman McInnes { 4030e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 4031dfbe8321SBarry Smith PetscErrorCode ierr; 4032b2002411SLois Curfman McInnes 4033b2002411SLois Curfman McInnes PetscFunctionBegin; 4034b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 4035c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 4036b2002411SLois Curfman McInnes PetscFunctionReturn(0); 4037b2002411SLois Curfman McInnes } 4038da9b6338SBarry Smith 4039da9b6338SBarry Smith #undef __FUNCT__ 4040da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 40417087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 4042da9b6338SBarry Smith { 4043dfbe8321SBarry Smith PetscErrorCode ierr; 404477431f27SBarry Smith PetscInt N,i,j; 4045da9b6338SBarry Smith Vec u,uh,fh; 4046da9b6338SBarry Smith PetscScalar value; 4047da9b6338SBarry Smith PetscReal norm; 4048da9b6338SBarry Smith 4049da9b6338SBarry Smith PetscFunctionBegin; 4050da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 4051da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 4052da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 4053da9b6338SBarry Smith 4054da9b6338SBarry Smith /* currently only works for sequential */ 4055da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 4056da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 4057da9b6338SBarry Smith for (i=0; i<N; i++) { 4058da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 405977431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 4060da9b6338SBarry Smith for (j=-10; j<11; j++) { 4061ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 4062da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 40633ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 4064da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 406577431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 4066da9b6338SBarry Smith value = -value; 4067da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 4068da9b6338SBarry Smith } 4069da9b6338SBarry Smith } 40706bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 40716bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 4072da9b6338SBarry Smith PetscFunctionReturn(0); 4073da9b6338SBarry Smith } 407471f87433Sdalcinl 407571f87433Sdalcinl #undef __FUNCT__ 4076fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 407771f87433Sdalcinl /*@ 4078fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 407971f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 408071f87433Sdalcinl Newton method. 408171f87433Sdalcinl 40823f9fe445SBarry Smith Logically Collective on SNES 408371f87433Sdalcinl 408471f87433Sdalcinl Input Parameters: 408571f87433Sdalcinl + snes - SNES context 408671f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 408771f87433Sdalcinl 408864ba62caSBarry Smith Options Database: 408964ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 409064ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 409164ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 409264ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 409364ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 409464ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 409564ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 409664ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 409764ba62caSBarry Smith 409871f87433Sdalcinl Notes: 409971f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 410071f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 410171f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 410271f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 410371f87433Sdalcinl solver. 410471f87433Sdalcinl 410571f87433Sdalcinl Level: advanced 410671f87433Sdalcinl 410771f87433Sdalcinl Reference: 410871f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 410971f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 411071f87433Sdalcinl 411171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 411271f87433Sdalcinl 4113fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 411471f87433Sdalcinl @*/ 41157087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 411671f87433Sdalcinl { 411771f87433Sdalcinl PetscFunctionBegin; 41180700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4119acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 412071f87433Sdalcinl snes->ksp_ewconv = flag; 412171f87433Sdalcinl PetscFunctionReturn(0); 412271f87433Sdalcinl } 412371f87433Sdalcinl 412471f87433Sdalcinl #undef __FUNCT__ 4125fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 412671f87433Sdalcinl /*@ 4127fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 412871f87433Sdalcinl for computing relative tolerance for linear solvers within an 412971f87433Sdalcinl inexact Newton method. 413071f87433Sdalcinl 413171f87433Sdalcinl Not Collective 413271f87433Sdalcinl 413371f87433Sdalcinl Input Parameter: 413471f87433Sdalcinl . snes - SNES context 413571f87433Sdalcinl 413671f87433Sdalcinl Output Parameter: 413771f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 413871f87433Sdalcinl 413971f87433Sdalcinl Notes: 414071f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 414171f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 414271f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 414371f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 414471f87433Sdalcinl solver. 414571f87433Sdalcinl 414671f87433Sdalcinl Level: advanced 414771f87433Sdalcinl 414871f87433Sdalcinl Reference: 414971f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 415071f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 415171f87433Sdalcinl 415271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 415371f87433Sdalcinl 4154fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 415571f87433Sdalcinl @*/ 41567087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 415771f87433Sdalcinl { 415871f87433Sdalcinl PetscFunctionBegin; 41590700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 416071f87433Sdalcinl PetscValidPointer(flag,2); 416171f87433Sdalcinl *flag = snes->ksp_ewconv; 416271f87433Sdalcinl PetscFunctionReturn(0); 416371f87433Sdalcinl } 416471f87433Sdalcinl 416571f87433Sdalcinl #undef __FUNCT__ 4166fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 416771f87433Sdalcinl /*@ 4168fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 416971f87433Sdalcinl convergence criteria for the linear solvers within an inexact 417071f87433Sdalcinl Newton method. 417171f87433Sdalcinl 41723f9fe445SBarry Smith Logically Collective on SNES 417371f87433Sdalcinl 417471f87433Sdalcinl Input Parameters: 417571f87433Sdalcinl + snes - SNES context 417671f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 417771f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 417871f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 417971f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 418071f87433Sdalcinl (0 <= gamma2 <= 1) 418171f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 418271f87433Sdalcinl . alpha2 - power for safeguard 418371f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 418471f87433Sdalcinl 418571f87433Sdalcinl Note: 418671f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 418771f87433Sdalcinl 418871f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 418971f87433Sdalcinl 419071f87433Sdalcinl Level: advanced 419171f87433Sdalcinl 419271f87433Sdalcinl Reference: 419371f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 419471f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 419571f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 419671f87433Sdalcinl 419771f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 419871f87433Sdalcinl 4199fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 420071f87433Sdalcinl @*/ 42017087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 420271f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 420371f87433Sdalcinl { 4204fa9f3622SBarry Smith SNESKSPEW *kctx; 420571f87433Sdalcinl PetscFunctionBegin; 42060700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4207fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4208e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 4209c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 4210c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 4211c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 4212c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 4213c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 4214c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 4215c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 421671f87433Sdalcinl 421771f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 421871f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 421971f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 422071f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 422171f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 422271f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 422371f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 422471f87433Sdalcinl 422571f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 4226e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 422771f87433Sdalcinl } 422871f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 4229e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 423071f87433Sdalcinl } 423171f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 4232e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 423371f87433Sdalcinl } 423471f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 4235e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 423671f87433Sdalcinl } 423771f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 4238e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 423971f87433Sdalcinl } 424071f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 4241e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 424271f87433Sdalcinl } 424371f87433Sdalcinl PetscFunctionReturn(0); 424471f87433Sdalcinl } 424571f87433Sdalcinl 424671f87433Sdalcinl #undef __FUNCT__ 4247fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 424871f87433Sdalcinl /*@ 4249fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 425071f87433Sdalcinl convergence criteria for the linear solvers within an inexact 425171f87433Sdalcinl Newton method. 425271f87433Sdalcinl 425371f87433Sdalcinl Not Collective 425471f87433Sdalcinl 425571f87433Sdalcinl Input Parameters: 425671f87433Sdalcinl snes - SNES context 425771f87433Sdalcinl 425871f87433Sdalcinl Output Parameters: 425971f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 426071f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 426171f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 426271f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 426371f87433Sdalcinl (0 <= gamma2 <= 1) 426471f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 426571f87433Sdalcinl . alpha2 - power for safeguard 426671f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 426771f87433Sdalcinl 426871f87433Sdalcinl Level: advanced 426971f87433Sdalcinl 427071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 427171f87433Sdalcinl 4272fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 427371f87433Sdalcinl @*/ 42747087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 427571f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 427671f87433Sdalcinl { 4277fa9f3622SBarry Smith SNESKSPEW *kctx; 427871f87433Sdalcinl PetscFunctionBegin; 42790700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4280fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4281e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 428271f87433Sdalcinl if (version) *version = kctx->version; 428371f87433Sdalcinl if (rtol_0) *rtol_0 = kctx->rtol_0; 428471f87433Sdalcinl if (rtol_max) *rtol_max = kctx->rtol_max; 428571f87433Sdalcinl if (gamma) *gamma = kctx->gamma; 428671f87433Sdalcinl if (alpha) *alpha = kctx->alpha; 428771f87433Sdalcinl if (alpha2) *alpha2 = kctx->alpha2; 428871f87433Sdalcinl if (threshold) *threshold = kctx->threshold; 428971f87433Sdalcinl PetscFunctionReturn(0); 429071f87433Sdalcinl } 429171f87433Sdalcinl 429271f87433Sdalcinl #undef __FUNCT__ 4293fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 4294fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 429571f87433Sdalcinl { 429671f87433Sdalcinl PetscErrorCode ierr; 4297fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 429871f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 429971f87433Sdalcinl 430071f87433Sdalcinl PetscFunctionBegin; 4301e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 430271f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 430371f87433Sdalcinl rtol = kctx->rtol_0; 430471f87433Sdalcinl } else { 430571f87433Sdalcinl if (kctx->version == 1) { 430671f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 430771f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 430871f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 430971f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 431071f87433Sdalcinl } else if (kctx->version == 2) { 431171f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 431271f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 431371f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 431471f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 431571f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 431671f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 431771f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 431871f87433Sdalcinl stol = PetscMax(rtol,stol); 431971f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 432071f87433Sdalcinl /* safeguard: avoid oversolving */ 432171f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 432271f87433Sdalcinl stol = PetscMax(rtol,stol); 432371f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 4324e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 432571f87433Sdalcinl } 432671f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 432771f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 432871f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 432971f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 433071f87433Sdalcinl PetscFunctionReturn(0); 433171f87433Sdalcinl } 433271f87433Sdalcinl 433371f87433Sdalcinl #undef __FUNCT__ 4334fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 4335fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 433671f87433Sdalcinl { 433771f87433Sdalcinl PetscErrorCode ierr; 4338fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 433971f87433Sdalcinl PCSide pcside; 434071f87433Sdalcinl Vec lres; 434171f87433Sdalcinl 434271f87433Sdalcinl PetscFunctionBegin; 4343e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 434471f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 434571f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 434671f87433Sdalcinl if (kctx->version == 1) { 4347b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 434871f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 434971f87433Sdalcinl /* KSP residual is true linear residual */ 435071f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 435171f87433Sdalcinl } else { 435271f87433Sdalcinl /* KSP residual is preconditioned residual */ 435371f87433Sdalcinl /* compute true linear residual norm */ 435471f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 435571f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 435671f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 435771f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 43586bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 435971f87433Sdalcinl } 436071f87433Sdalcinl } 436171f87433Sdalcinl PetscFunctionReturn(0); 436271f87433Sdalcinl } 436371f87433Sdalcinl 436471f87433Sdalcinl #undef __FUNCT__ 436571f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 436671f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 436771f87433Sdalcinl { 436871f87433Sdalcinl PetscErrorCode ierr; 436971f87433Sdalcinl 437071f87433Sdalcinl PetscFunctionBegin; 4371fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 437271f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 4373fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 437471f87433Sdalcinl PetscFunctionReturn(0); 437571f87433Sdalcinl } 43766c699258SBarry Smith 43776c699258SBarry Smith #undef __FUNCT__ 43786c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 43796c699258SBarry Smith /*@ 43806c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 43816c699258SBarry Smith 43823f9fe445SBarry Smith Logically Collective on SNES 43836c699258SBarry Smith 43846c699258SBarry Smith Input Parameters: 43856c699258SBarry Smith + snes - the preconditioner context 43866c699258SBarry Smith - dm - the dm 43876c699258SBarry Smith 43886c699258SBarry Smith Level: intermediate 43896c699258SBarry Smith 43906c699258SBarry Smith 43916c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 43926c699258SBarry Smith @*/ 43937087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 43946c699258SBarry Smith { 43956c699258SBarry Smith PetscErrorCode ierr; 4396345fed2cSBarry Smith KSP ksp; 43976cab3a1bSJed Brown SNESDM sdm; 43986c699258SBarry Smith 43996c699258SBarry Smith PetscFunctionBegin; 44000700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4401d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 44026cab3a1bSJed Brown if (snes->dm) { /* Move the SNESDM context over to the new DM unless the new DM already has one */ 44036cab3a1bSJed Brown PetscContainer oldcontainer,container; 44046cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 44056cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr); 4406116d1032SJed Brown if (oldcontainer && snes->dmAuto && !container) { 44076cab3a1bSJed Brown ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr); 44086cab3a1bSJed Brown ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr); 44096cab3a1bSJed Brown if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */ 44106cab3a1bSJed Brown sdm->originaldm = dm; 44116cab3a1bSJed Brown } 44126cab3a1bSJed Brown } 44136bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 44146cab3a1bSJed Brown } 44156c699258SBarry Smith snes->dm = dm; 4416116d1032SJed Brown snes->dmAuto = PETSC_FALSE; 4417345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4418345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4419f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 44202c155ee1SBarry Smith if (snes->pc) { 44212c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 4422c40d0f55SPeter Brune ierr = SNESSetPCSide(snes,snes->pcside);CHKERRQ(ierr); 44232c155ee1SBarry Smith } 44246c699258SBarry Smith PetscFunctionReturn(0); 44256c699258SBarry Smith } 44266c699258SBarry Smith 44276c699258SBarry Smith #undef __FUNCT__ 44286c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 44296c699258SBarry Smith /*@ 44306c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 44316c699258SBarry Smith 44323f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 44336c699258SBarry Smith 44346c699258SBarry Smith Input Parameter: 44356c699258SBarry Smith . snes - the preconditioner context 44366c699258SBarry Smith 44376c699258SBarry Smith Output Parameter: 44386c699258SBarry Smith . dm - the dm 44396c699258SBarry Smith 44406c699258SBarry Smith Level: intermediate 44416c699258SBarry Smith 44426c699258SBarry Smith 44436c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 44446c699258SBarry Smith @*/ 44457087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 44466c699258SBarry Smith { 44476cab3a1bSJed Brown PetscErrorCode ierr; 44486cab3a1bSJed Brown 44496c699258SBarry Smith PetscFunctionBegin; 44500700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 44516cab3a1bSJed Brown if (!snes->dm) { 44526cab3a1bSJed Brown ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr); 4453116d1032SJed Brown snes->dmAuto = PETSC_TRUE; 44546cab3a1bSJed Brown } 44556c699258SBarry Smith *dm = snes->dm; 44566c699258SBarry Smith PetscFunctionReturn(0); 44576c699258SBarry Smith } 44580807856dSBarry Smith 445931823bd8SMatthew G Knepley #undef __FUNCT__ 446031823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 446131823bd8SMatthew G Knepley /*@ 4462fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 446331823bd8SMatthew G Knepley 446431823bd8SMatthew G Knepley Collective on SNES 446531823bd8SMatthew G Knepley 446631823bd8SMatthew G Knepley Input Parameters: 446731823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 446831823bd8SMatthew G Knepley - pc - the preconditioner object 446931823bd8SMatthew G Knepley 447031823bd8SMatthew G Knepley Notes: 447131823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 447231823bd8SMatthew G Knepley to configure it using the API). 447331823bd8SMatthew G Knepley 447431823bd8SMatthew G Knepley Level: developer 447531823bd8SMatthew G Knepley 447631823bd8SMatthew G Knepley .keywords: SNES, set, precondition 447731823bd8SMatthew G Knepley .seealso: SNESGetPC() 447831823bd8SMatthew G Knepley @*/ 447931823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 448031823bd8SMatthew G Knepley { 448131823bd8SMatthew G Knepley PetscErrorCode ierr; 448231823bd8SMatthew G Knepley 448331823bd8SMatthew G Knepley PetscFunctionBegin; 448431823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 448531823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 448631823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 448731823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4488bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 448931823bd8SMatthew G Knepley snes->pc = pc; 449031823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 449131823bd8SMatthew G Knepley PetscFunctionReturn(0); 449231823bd8SMatthew G Knepley } 449331823bd8SMatthew G Knepley 449431823bd8SMatthew G Knepley #undef __FUNCT__ 449531823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 449631823bd8SMatthew G Knepley /*@ 4497fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 449831823bd8SMatthew G Knepley 449931823bd8SMatthew G Knepley Not Collective 450031823bd8SMatthew G Knepley 450131823bd8SMatthew G Knepley Input Parameter: 450231823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 450331823bd8SMatthew G Knepley 450431823bd8SMatthew G Knepley Output Parameter: 450531823bd8SMatthew G Knepley . pc - preconditioner context 450631823bd8SMatthew G Knepley 450731823bd8SMatthew G Knepley Level: developer 450831823bd8SMatthew G Knepley 450931823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 451031823bd8SMatthew G Knepley .seealso: SNESSetPC() 451131823bd8SMatthew G Knepley @*/ 451231823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 451331823bd8SMatthew G Knepley { 451431823bd8SMatthew G Knepley PetscErrorCode ierr; 4515a64e098fSPeter Brune const char *optionsprefix; 451631823bd8SMatthew G Knepley 451731823bd8SMatthew G Knepley PetscFunctionBegin; 451831823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 451931823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 452031823bd8SMatthew G Knepley if (!snes->pc) { 452131823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm,&snes->pc);CHKERRQ(ierr); 45224a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr); 452331823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes,snes->pc);CHKERRQ(ierr); 4524a64e098fSPeter Brune ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr); 4525a64e098fSPeter Brune ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr); 4526a64e098fSPeter Brune ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr); 452731823bd8SMatthew G Knepley } 452831823bd8SMatthew G Knepley *pc = snes->pc; 452931823bd8SMatthew G Knepley PetscFunctionReturn(0); 453031823bd8SMatthew G Knepley } 453131823bd8SMatthew G Knepley 4532c40d0f55SPeter Brune 4533c40d0f55SPeter Brune #undef __FUNCT__ 4534c40d0f55SPeter Brune #define __FUNCT__ "SNESSetPCSide" 4535c40d0f55SPeter Brune /*@ 4536c40d0f55SPeter Brune SNESSetPCSide - Sets the preconditioning side. 4537c40d0f55SPeter Brune 4538c40d0f55SPeter Brune Logically Collective on SNES 4539c40d0f55SPeter Brune 4540c40d0f55SPeter Brune Input Parameter: 4541c40d0f55SPeter Brune . snes - iterative context obtained from SNESCreate() 4542c40d0f55SPeter Brune 4543c40d0f55SPeter Brune Output Parameter: 4544c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 4545c40d0f55SPeter Brune .vb 4546c40d0f55SPeter Brune PC_LEFT - left preconditioning (default) 4547c40d0f55SPeter Brune PC_RIGHT - right preconditioning 4548c40d0f55SPeter Brune .ve 4549c40d0f55SPeter Brune 4550c40d0f55SPeter Brune Options Database Keys: 4551c40d0f55SPeter Brune . -snes_pc_side <right,left> 4552c40d0f55SPeter Brune 4553c40d0f55SPeter Brune Level: intermediate 4554c40d0f55SPeter Brune 4555c40d0f55SPeter Brune .keywords: SNES, set, right, left, side, preconditioner, flag 4556c40d0f55SPeter Brune 4557c40d0f55SPeter Brune .seealso: SNESGetPCSide(), KSPSetPCSide() 4558c40d0f55SPeter Brune @*/ 4559c40d0f55SPeter Brune PetscErrorCode SNESSetPCSide(SNES snes,PCSide side) 4560c40d0f55SPeter Brune { 4561c40d0f55SPeter Brune PetscFunctionBegin; 4562c40d0f55SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4563c40d0f55SPeter Brune PetscValidLogicalCollectiveEnum(snes,side,2); 4564c40d0f55SPeter Brune snes->pcside = side; 4565c40d0f55SPeter Brune PetscFunctionReturn(0); 4566c40d0f55SPeter Brune } 4567c40d0f55SPeter Brune 4568c40d0f55SPeter Brune #undef __FUNCT__ 4569c40d0f55SPeter Brune #define __FUNCT__ "SNESGetPCSide" 4570c40d0f55SPeter Brune /*@ 4571c40d0f55SPeter Brune SNESGetPCSide - Gets the preconditioning side. 4572c40d0f55SPeter Brune 4573c40d0f55SPeter Brune Not Collective 4574c40d0f55SPeter Brune 4575c40d0f55SPeter Brune Input Parameter: 4576c40d0f55SPeter Brune . snes - iterative context obtained from SNESCreate() 4577c40d0f55SPeter Brune 4578c40d0f55SPeter Brune Output Parameter: 4579c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 4580c40d0f55SPeter Brune .vb 4581c40d0f55SPeter Brune PC_LEFT - left preconditioning (default) 4582c40d0f55SPeter Brune PC_RIGHT - right preconditioning 4583c40d0f55SPeter Brune .ve 4584c40d0f55SPeter Brune 4585c40d0f55SPeter Brune Level: intermediate 4586c40d0f55SPeter Brune 4587c40d0f55SPeter Brune .keywords: SNES, get, right, left, side, preconditioner, flag 4588c40d0f55SPeter Brune 4589c40d0f55SPeter Brune .seealso: SNESSetPCSide(), KSPGetPCSide() 4590c40d0f55SPeter Brune @*/ 4591c40d0f55SPeter Brune PetscErrorCode SNESGetPCSide(SNES snes,PCSide *side) 4592c40d0f55SPeter Brune { 4593c40d0f55SPeter Brune PetscFunctionBegin; 4594c40d0f55SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4595c40d0f55SPeter Brune PetscValidPointer(side,2); 4596c40d0f55SPeter Brune *side = snes->pcside; 4597c40d0f55SPeter Brune PetscFunctionReturn(0); 4598c40d0f55SPeter Brune } 4599c40d0f55SPeter Brune 46009e764e56SPeter Brune #undef __FUNCT__ 4601f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch" 46029e764e56SPeter Brune /*@ 46038141a3b9SPeter Brune SNESSetSNESLineSearch - Sets the linesearch on the SNES instance. 46049e764e56SPeter Brune 46059e764e56SPeter Brune Collective on SNES 46069e764e56SPeter Brune 46079e764e56SPeter Brune Input Parameters: 46089e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 46099e764e56SPeter Brune - linesearch - the linesearch object 46109e764e56SPeter Brune 46119e764e56SPeter Brune Notes: 4612f1c6b773SPeter Brune Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example, 46139e764e56SPeter Brune to configure it using the API). 46149e764e56SPeter Brune 46159e764e56SPeter Brune Level: developer 46169e764e56SPeter Brune 46179e764e56SPeter Brune .keywords: SNES, set, linesearch 4618f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch() 46199e764e56SPeter Brune @*/ 4620f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch) 46219e764e56SPeter Brune { 46229e764e56SPeter Brune PetscErrorCode ierr; 46239e764e56SPeter Brune 46249e764e56SPeter Brune PetscFunctionBegin; 46259e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4626f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 46279e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 46289e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 4629f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 46309e764e56SPeter Brune snes->linesearch = linesearch; 46319e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 46329e764e56SPeter Brune PetscFunctionReturn(0); 46339e764e56SPeter Brune } 46349e764e56SPeter Brune 46359e764e56SPeter Brune #undef __FUNCT__ 4636f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch" 4637ea5d4fccSPeter Brune /*@C 46388141a3b9SPeter Brune SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 46398141a3b9SPeter Brune or creates a default line search instance associated with the SNES and returns it. 46409e764e56SPeter Brune 46419e764e56SPeter Brune Not Collective 46429e764e56SPeter Brune 46439e764e56SPeter Brune Input Parameter: 46449e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 46459e764e56SPeter Brune 46469e764e56SPeter Brune Output Parameter: 46479e764e56SPeter Brune . linesearch - linesearch context 46489e764e56SPeter Brune 46499e764e56SPeter Brune Level: developer 46509e764e56SPeter Brune 46519e764e56SPeter Brune .keywords: SNES, get, linesearch 4652f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch() 46539e764e56SPeter Brune @*/ 4654f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch) 46559e764e56SPeter Brune { 46569e764e56SPeter Brune PetscErrorCode ierr; 46579e764e56SPeter Brune const char *optionsprefix; 46589e764e56SPeter Brune 46599e764e56SPeter Brune PetscFunctionBegin; 46609e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 46619e764e56SPeter Brune PetscValidPointer(linesearch, 2); 46629e764e56SPeter Brune if (!snes->linesearch) { 46639e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 4664f1c6b773SPeter Brune ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr); 4665f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 4666b1dca40bSPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 46679e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 46689e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 46699e764e56SPeter Brune } 46709e764e56SPeter Brune *linesearch = snes->linesearch; 46719e764e56SPeter Brune PetscFunctionReturn(0); 46729e764e56SPeter Brune } 46739e764e56SPeter Brune 467469b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4675c6db04a5SJed Brown #include <mex.h> 467669b4f73cSBarry Smith 46778f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 46788f6e6473SBarry Smith 46790807856dSBarry Smith #undef __FUNCT__ 46800807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 46810807856dSBarry Smith /* 46820807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 46830807856dSBarry Smith SNESSetFunctionMatlab(). 46840807856dSBarry Smith 46850807856dSBarry Smith Collective on SNES 46860807856dSBarry Smith 46870807856dSBarry Smith Input Parameters: 46880807856dSBarry Smith + snes - the SNES context 46890807856dSBarry Smith - x - input vector 46900807856dSBarry Smith 46910807856dSBarry Smith Output Parameter: 46920807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 46930807856dSBarry Smith 46940807856dSBarry Smith Notes: 46950807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 46960807856dSBarry Smith implementations, so most users would not generally call this routine 46970807856dSBarry Smith themselves. 46980807856dSBarry Smith 46990807856dSBarry Smith Level: developer 47000807856dSBarry Smith 47010807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 47020807856dSBarry Smith 47030807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 470461b2408cSBarry Smith */ 47057087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 47060807856dSBarry Smith { 4707e650e774SBarry Smith PetscErrorCode ierr; 47088f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 47098f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 47108f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 471191621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 4712e650e774SBarry Smith 47130807856dSBarry Smith PetscFunctionBegin; 47140807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 47150807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 47160807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 47170807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 47180807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 47190807856dSBarry Smith 47200807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 4721e650e774SBarry Smith 472291621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4723e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4724e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 472591621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 472691621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 472791621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 47288f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 47298f6e6473SBarry Smith prhs[4] = sctx->ctx; 4730b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 4731e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4732e650e774SBarry Smith mxDestroyArray(prhs[0]); 4733e650e774SBarry Smith mxDestroyArray(prhs[1]); 4734e650e774SBarry Smith mxDestroyArray(prhs[2]); 47358f6e6473SBarry Smith mxDestroyArray(prhs[3]); 4736e650e774SBarry Smith mxDestroyArray(plhs[0]); 47370807856dSBarry Smith PetscFunctionReturn(0); 47380807856dSBarry Smith } 47390807856dSBarry Smith 47400807856dSBarry Smith 47410807856dSBarry Smith #undef __FUNCT__ 47420807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 474361b2408cSBarry Smith /* 47440807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 47450807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4746e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 47470807856dSBarry Smith 47480807856dSBarry Smith Logically Collective on SNES 47490807856dSBarry Smith 47500807856dSBarry Smith Input Parameters: 47510807856dSBarry Smith + snes - the SNES context 47520807856dSBarry Smith . r - vector to store function value 47530807856dSBarry Smith - func - function evaluation routine 47540807856dSBarry Smith 47550807856dSBarry Smith Calling sequence of func: 475661b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 47570807856dSBarry Smith 47580807856dSBarry Smith 47590807856dSBarry Smith Notes: 47600807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 47610807856dSBarry Smith $ f'(x) x = -f(x), 47620807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 47630807856dSBarry Smith 47640807856dSBarry Smith Level: beginner 47650807856dSBarry Smith 47660807856dSBarry Smith .keywords: SNES, nonlinear, set, function 47670807856dSBarry Smith 47680807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 476961b2408cSBarry Smith */ 47707087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 47710807856dSBarry Smith { 47720807856dSBarry Smith PetscErrorCode ierr; 47738f6e6473SBarry Smith SNESMatlabContext *sctx; 47740807856dSBarry Smith 47750807856dSBarry Smith PetscFunctionBegin; 47768f6e6473SBarry Smith /* currently sctx is memory bleed */ 47778f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 47788f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 47798f6e6473SBarry Smith /* 47808f6e6473SBarry Smith This should work, but it doesn't 47818f6e6473SBarry Smith sctx->ctx = ctx; 47828f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 47838f6e6473SBarry Smith */ 47848f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 47858f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 47860807856dSBarry Smith PetscFunctionReturn(0); 47870807856dSBarry Smith } 478869b4f73cSBarry Smith 478961b2408cSBarry Smith #undef __FUNCT__ 479061b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 479161b2408cSBarry Smith /* 479261b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 479361b2408cSBarry Smith SNESSetJacobianMatlab(). 479461b2408cSBarry Smith 479561b2408cSBarry Smith Collective on SNES 479661b2408cSBarry Smith 479761b2408cSBarry Smith Input Parameters: 479861b2408cSBarry Smith + snes - the SNES context 479961b2408cSBarry Smith . x - input vector 480061b2408cSBarry Smith . A, B - the matrices 480161b2408cSBarry Smith - ctx - user context 480261b2408cSBarry Smith 480361b2408cSBarry Smith Output Parameter: 480461b2408cSBarry Smith . flag - structure of the matrix 480561b2408cSBarry Smith 480661b2408cSBarry Smith Level: developer 480761b2408cSBarry Smith 480861b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 480961b2408cSBarry Smith 481061b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 481161b2408cSBarry Smith @*/ 48127087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 481361b2408cSBarry Smith { 481461b2408cSBarry Smith PetscErrorCode ierr; 481561b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 481661b2408cSBarry Smith int nlhs = 2,nrhs = 6; 481761b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 481861b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 481961b2408cSBarry Smith 482061b2408cSBarry Smith PetscFunctionBegin; 482161b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 482261b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 482361b2408cSBarry Smith 482461b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 482561b2408cSBarry Smith 482661b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 482761b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 482861b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 482961b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 483061b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 483161b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 483261b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 483361b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 483461b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 483561b2408cSBarry Smith prhs[5] = sctx->ctx; 4836b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 483761b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 483861b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 483961b2408cSBarry Smith mxDestroyArray(prhs[0]); 484061b2408cSBarry Smith mxDestroyArray(prhs[1]); 484161b2408cSBarry Smith mxDestroyArray(prhs[2]); 484261b2408cSBarry Smith mxDestroyArray(prhs[3]); 484361b2408cSBarry Smith mxDestroyArray(prhs[4]); 484461b2408cSBarry Smith mxDestroyArray(plhs[0]); 484561b2408cSBarry Smith mxDestroyArray(plhs[1]); 484661b2408cSBarry Smith PetscFunctionReturn(0); 484761b2408cSBarry Smith } 484861b2408cSBarry Smith 484961b2408cSBarry Smith 485061b2408cSBarry Smith #undef __FUNCT__ 485161b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 485261b2408cSBarry Smith /* 485361b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 485461b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4855e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 485661b2408cSBarry Smith 485761b2408cSBarry Smith Logically Collective on SNES 485861b2408cSBarry Smith 485961b2408cSBarry Smith Input Parameters: 486061b2408cSBarry Smith + snes - the SNES context 486161b2408cSBarry Smith . A,B - Jacobian matrices 486261b2408cSBarry Smith . func - function evaluation routine 486361b2408cSBarry Smith - ctx - user context 486461b2408cSBarry Smith 486561b2408cSBarry Smith Calling sequence of func: 486661b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 486761b2408cSBarry Smith 486861b2408cSBarry Smith 486961b2408cSBarry Smith Level: developer 487061b2408cSBarry Smith 487161b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 487261b2408cSBarry Smith 487361b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 487461b2408cSBarry Smith */ 48757087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 487661b2408cSBarry Smith { 487761b2408cSBarry Smith PetscErrorCode ierr; 487861b2408cSBarry Smith SNESMatlabContext *sctx; 487961b2408cSBarry Smith 488061b2408cSBarry Smith PetscFunctionBegin; 488161b2408cSBarry Smith /* currently sctx is memory bleed */ 488261b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 488361b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 488461b2408cSBarry Smith /* 488561b2408cSBarry Smith This should work, but it doesn't 488661b2408cSBarry Smith sctx->ctx = ctx; 488761b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 488861b2408cSBarry Smith */ 488961b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 489061b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 489161b2408cSBarry Smith PetscFunctionReturn(0); 489261b2408cSBarry Smith } 489369b4f73cSBarry Smith 4894f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4895f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4896f9eb7ae2SShri Abhyankar /* 4897f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4898f9eb7ae2SShri Abhyankar 4899f9eb7ae2SShri Abhyankar Collective on SNES 4900f9eb7ae2SShri Abhyankar 4901f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4902f9eb7ae2SShri Abhyankar @*/ 49037087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4904f9eb7ae2SShri Abhyankar { 4905f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 490648f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4907f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4908f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4909f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4910f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4911f9eb7ae2SShri Abhyankar 4912f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4913f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4914f9eb7ae2SShri Abhyankar 4915f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4916f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4917f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4918f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4919f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4920f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4921f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4922f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4923f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4924f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4925f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4926f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4927f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4928f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4929f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4930f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4931f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4932f9eb7ae2SShri Abhyankar } 4933f9eb7ae2SShri Abhyankar 4934f9eb7ae2SShri Abhyankar 4935f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4936f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4937f9eb7ae2SShri Abhyankar /* 4938e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4939f9eb7ae2SShri Abhyankar 4940f9eb7ae2SShri Abhyankar Level: developer 4941f9eb7ae2SShri Abhyankar 4942f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4943f9eb7ae2SShri Abhyankar 4944f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4945f9eb7ae2SShri Abhyankar */ 49467087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4947f9eb7ae2SShri Abhyankar { 4948f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4949f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4950f9eb7ae2SShri Abhyankar 4951f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4952f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4953f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4954f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4955f9eb7ae2SShri Abhyankar /* 4956f9eb7ae2SShri Abhyankar This should work, but it doesn't 4957f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4958f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4959f9eb7ae2SShri Abhyankar */ 4960f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4961f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4962f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4963f9eb7ae2SShri Abhyankar } 4964f9eb7ae2SShri Abhyankar 496569b4f73cSBarry Smith #endif 4966