19b94acceSBarry Smith 2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h> /*I "petscsnes.h" I*/ 36cab3a1bSJed Brown #include <petscdmshell.h> /*I "petscdmshell.h" I*/ 4a64e098fSPeter Brune #include <petscsys.h> /*I "petscsys.h" I*/ 59b94acceSBarry Smith 6ace3abfcSBarry Smith PetscBool SNESRegisterAllCalled = PETSC_FALSE; 78ba1e511SMatthew Knepley PetscFList SNESList = PETSC_NULL; 88ba1e511SMatthew Knepley 98ba1e511SMatthew Knepley /* Logging support */ 107087cfbeSBarry Smith PetscClassId SNES_CLASSID; 11f1c6b773SPeter Brune PetscLogEvent SNES_Solve, SNES_FunctionEval, SNES_JacobianEval, SNES_GSEval; 12a09944afSBarry Smith 13a09944afSBarry Smith #undef __FUNCT__ 14e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged" 15e113a28aSBarry Smith /*@ 16e113a28aSBarry Smith SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged. 17e113a28aSBarry Smith 183f9fe445SBarry Smith Logically Collective on SNES 19e113a28aSBarry Smith 20e113a28aSBarry Smith Input Parameters: 21e113a28aSBarry Smith + snes - iterative context obtained from SNESCreate() 22e113a28aSBarry Smith - flg - PETSC_TRUE indicates you want the error generated 23e113a28aSBarry Smith 24e113a28aSBarry Smith Options database keys: 25e113a28aSBarry Smith . -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false) 26e113a28aSBarry Smith 27e113a28aSBarry Smith Level: intermediate 28e113a28aSBarry Smith 29e113a28aSBarry Smith Notes: 30e113a28aSBarry Smith Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve() 31e113a28aSBarry Smith to determine if it has converged. 32e113a28aSBarry Smith 33e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 34e113a28aSBarry Smith 35e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 36e113a28aSBarry Smith @*/ 377087cfbeSBarry Smith PetscErrorCode SNESSetErrorIfNotConverged(SNES snes,PetscBool flg) 38e113a28aSBarry Smith { 39e113a28aSBarry Smith PetscFunctionBegin; 40e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 41acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flg,2); 42e113a28aSBarry Smith snes->errorifnotconverged = flg; 43dd568438SSatish Balay 44e113a28aSBarry Smith PetscFunctionReturn(0); 45e113a28aSBarry Smith } 46e113a28aSBarry Smith 47e113a28aSBarry Smith #undef __FUNCT__ 48e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged" 49e113a28aSBarry Smith /*@ 50e113a28aSBarry Smith SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge? 51e113a28aSBarry Smith 52e113a28aSBarry Smith Not Collective 53e113a28aSBarry Smith 54e113a28aSBarry Smith Input Parameter: 55e113a28aSBarry Smith . snes - iterative context obtained from SNESCreate() 56e113a28aSBarry Smith 57e113a28aSBarry Smith Output Parameter: 58e113a28aSBarry Smith . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE 59e113a28aSBarry Smith 60e113a28aSBarry Smith Level: intermediate 61e113a28aSBarry Smith 62e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 63e113a28aSBarry Smith 64e113a28aSBarry Smith .seealso: SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 65e113a28aSBarry Smith @*/ 667087cfbeSBarry Smith PetscErrorCode SNESGetErrorIfNotConverged(SNES snes,PetscBool *flag) 67e113a28aSBarry Smith { 68e113a28aSBarry Smith PetscFunctionBegin; 69e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 70e113a28aSBarry Smith PetscValidPointer(flag,2); 71e113a28aSBarry Smith *flag = snes->errorifnotconverged; 72e113a28aSBarry Smith PetscFunctionReturn(0); 73e113a28aSBarry Smith } 74e113a28aSBarry Smith 75e113a28aSBarry Smith #undef __FUNCT__ 764936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError" 77e725d27bSBarry Smith /*@ 784936397dSBarry Smith SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not 794936397dSBarry Smith in the functions domain. For example, negative pressure. 804936397dSBarry Smith 813f9fe445SBarry Smith Logically Collective on SNES 824936397dSBarry Smith 834936397dSBarry Smith Input Parameters: 846a388c36SPeter Brune . snes - the SNES context 854936397dSBarry Smith 8628529972SSatish Balay Level: advanced 874936397dSBarry Smith 884936397dSBarry Smith .keywords: SNES, view 894936397dSBarry Smith 904936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction() 914936397dSBarry Smith @*/ 927087cfbeSBarry Smith PetscErrorCode SNESSetFunctionDomainError(SNES snes) 934936397dSBarry Smith { 944936397dSBarry Smith PetscFunctionBegin; 950700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 964936397dSBarry Smith snes->domainerror = PETSC_TRUE; 974936397dSBarry Smith PetscFunctionReturn(0); 984936397dSBarry Smith } 994936397dSBarry Smith 1006a388c36SPeter Brune 1016a388c36SPeter Brune #undef __FUNCT__ 1026a388c36SPeter Brune #define __FUNCT__ "SNESGetFunctionDomainError" 1036a388c36SPeter Brune /*@ 104c77b2880SPeter Brune SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction; 1056a388c36SPeter Brune 1066a388c36SPeter Brune Logically Collective on SNES 1076a388c36SPeter Brune 1086a388c36SPeter Brune Input Parameters: 1096a388c36SPeter Brune . snes - the SNES context 1106a388c36SPeter Brune 1116a388c36SPeter Brune Output Parameters: 1126a388c36SPeter Brune . domainerror Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise. 1136a388c36SPeter Brune 1146a388c36SPeter Brune Level: advanced 1156a388c36SPeter Brune 1166a388c36SPeter Brune .keywords: SNES, view 1176a388c36SPeter Brune 1186a388c36SPeter Brune .seealso: SNESSetFunctionDomainError, SNESComputeFunction() 1196a388c36SPeter Brune @*/ 1206a388c36SPeter Brune PetscErrorCode SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror) 1216a388c36SPeter Brune { 1226a388c36SPeter Brune PetscFunctionBegin; 1236a388c36SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1246a388c36SPeter Brune PetscValidPointer(domainerror, 2); 1256a388c36SPeter Brune *domainerror = snes->domainerror; 1266a388c36SPeter Brune PetscFunctionReturn(0); 1276a388c36SPeter Brune } 1286a388c36SPeter Brune 1296a388c36SPeter Brune 1304936397dSBarry Smith #undef __FUNCT__ 1314a2ae208SSatish Balay #define __FUNCT__ "SNESView" 1327e2c5f70SBarry Smith /*@C 1339b94acceSBarry Smith SNESView - Prints the SNES data structure. 1349b94acceSBarry Smith 1354c49b128SBarry Smith Collective on SNES 136fee21e36SBarry Smith 137c7afd0dbSLois Curfman McInnes Input Parameters: 138c7afd0dbSLois Curfman McInnes + SNES - the SNES context 139c7afd0dbSLois Curfman McInnes - viewer - visualization context 140c7afd0dbSLois Curfman McInnes 1419b94acceSBarry Smith Options Database Key: 142c8a8ba5cSLois Curfman McInnes . -snes_view - Calls SNESView() at end of SNESSolve() 1439b94acceSBarry Smith 1449b94acceSBarry Smith Notes: 1459b94acceSBarry Smith The available visualization contexts include 146b0a32e0cSBarry Smith + PETSC_VIEWER_STDOUT_SELF - standard output (default) 147b0a32e0cSBarry Smith - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 148c8a8ba5cSLois Curfman McInnes output where only the first processor opens 149c8a8ba5cSLois Curfman McInnes the file. All other processors send their 150c8a8ba5cSLois Curfman McInnes data to the first processor to print. 1519b94acceSBarry Smith 1523e081fefSLois Curfman McInnes The user can open an alternative visualization context with 153b0a32e0cSBarry Smith PetscViewerASCIIOpen() - output to a specified file. 1549b94acceSBarry Smith 15536851e7fSLois Curfman McInnes Level: beginner 15636851e7fSLois Curfman McInnes 1579b94acceSBarry Smith .keywords: SNES, view 1589b94acceSBarry Smith 159b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen() 1609b94acceSBarry Smith @*/ 1617087cfbeSBarry Smith PetscErrorCode SNESView(SNES snes,PetscViewer viewer) 1629b94acceSBarry Smith { 163fa9f3622SBarry Smith SNESKSPEW *kctx; 164dfbe8321SBarry Smith PetscErrorCode ierr; 16594b7f48cSBarry Smith KSP ksp; 1667f1410a3SPeter Brune SNESLineSearch linesearch; 167ace3abfcSBarry Smith PetscBool iascii,isstring; 1689b94acceSBarry Smith 1693a40ed3dSBarry Smith PetscFunctionBegin; 1700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1713050cee2SBarry Smith if (!viewer) { 1727adad957SLisandro Dalcin ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 1733050cee2SBarry Smith } 1740700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 175c9780b6fSBarry Smith PetscCheckSameComm(snes,1,viewer,2); 17674679c65SBarry Smith 177251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 178251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 17932077d6dSBarry Smith if (iascii) { 180317d6ea6SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr); 181e7788613SBarry Smith if (snes->ops->view) { 182b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 183e7788613SBarry Smith ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 184b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1850ef38995SBarry Smith } 18677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr); 187a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%G, absolute=%G, solution=%G\n", 188c60f73f4SPeter Brune snes->rtol,snes->abstol,snes->stol);CHKERRQ(ierr); 18977431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr); 19077431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr); 19117fe4bdfSPeter Brune if (snes->gridsequence) { 19217fe4bdfSPeter Brune ierr = PetscViewerASCIIPrintf(viewer," total number of grid sequence refinements=%D\n",snes->gridsequence);CHKERRQ(ierr); 19317fe4bdfSPeter Brune } 1949b94acceSBarry Smith if (snes->ksp_ewconv) { 195fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 1969b94acceSBarry Smith if (kctx) { 19777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr); 198a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr); 199a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr); 2009b94acceSBarry Smith } 2019b94acceSBarry Smith } 202eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 203eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n");CHKERRQ(ierr); 204eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 205eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr); 206eb1f6c34SBarry Smith } 207eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 208eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n");CHKERRQ(ierr); 209eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 21042f4f86dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr); 211eb1f6c34SBarry Smith } 2120f5bd95cSBarry Smith } else if (isstring) { 213317d6ea6SBarry Smith const char *type; 214454a90a3SBarry Smith ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 215b0a32e0cSBarry Smith ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr); 21619bcc07fSBarry Smith } 21742f4f86dSBarry Smith if (snes->pc && snes->usespc) { 2184a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2194a0c5b0cSMatthew G Knepley ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr); 2204a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2214a0c5b0cSMatthew G Knepley } 2222c155ee1SBarry Smith if (snes->usesksp) { 2232c155ee1SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 224b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 22594b7f48cSBarry Smith ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 226b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2272c155ee1SBarry Smith } 2287f1410a3SPeter Brune if (snes->linesearch) { 2297f1410a3SPeter Brune ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2307f1410a3SPeter Brune ierr = SNESGetSNESLineSearch(snes, &linesearch);CHKERRQ(ierr); 2317f1410a3SPeter Brune ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr); 2327f1410a3SPeter Brune ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2337f1410a3SPeter Brune } 2343a40ed3dSBarry Smith PetscFunctionReturn(0); 2359b94acceSBarry Smith } 2369b94acceSBarry Smith 23776b2cf59SMatthew Knepley /* 23876b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 23976b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 24076b2cf59SMatthew Knepley */ 24176b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 242a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 2436849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 24476b2cf59SMatthew Knepley 245e74ef692SMatthew Knepley #undef __FUNCT__ 246e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker" 247ac226902SBarry Smith /*@C 24876b2cf59SMatthew Knepley SNESAddOptionsChecker - Adds an additional function to check for SNES options. 24976b2cf59SMatthew Knepley 25076b2cf59SMatthew Knepley Not Collective 25176b2cf59SMatthew Knepley 25276b2cf59SMatthew Knepley Input Parameter: 25376b2cf59SMatthew Knepley . snescheck - function that checks for options 25476b2cf59SMatthew Knepley 25576b2cf59SMatthew Knepley Level: developer 25676b2cf59SMatthew Knepley 25776b2cf59SMatthew Knepley .seealso: SNESSetFromOptions() 25876b2cf59SMatthew Knepley @*/ 2597087cfbeSBarry Smith PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 26076b2cf59SMatthew Knepley { 26176b2cf59SMatthew Knepley PetscFunctionBegin; 26276b2cf59SMatthew Knepley if (numberofsetfromoptions >= MAXSETFROMOPTIONS) { 263e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 26476b2cf59SMatthew Knepley } 26576b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 26676b2cf59SMatthew Knepley PetscFunctionReturn(0); 26776b2cf59SMatthew Knepley } 26876b2cf59SMatthew Knepley 2697087cfbeSBarry Smith extern PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 270aa3661deSLisandro Dalcin 271aa3661deSLisandro Dalcin #undef __FUNCT__ 272aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private" 273ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 274aa3661deSLisandro Dalcin { 275aa3661deSLisandro Dalcin Mat J; 276aa3661deSLisandro Dalcin KSP ksp; 277aa3661deSLisandro Dalcin PC pc; 278ace3abfcSBarry Smith PetscBool match; 279aa3661deSLisandro Dalcin PetscErrorCode ierr; 280aa3661deSLisandro Dalcin 281aa3661deSLisandro Dalcin PetscFunctionBegin; 2820700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 283aa3661deSLisandro Dalcin 28498613b67SLisandro Dalcin if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 28598613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 28698613b67SLisandro Dalcin ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr); 28798613b67SLisandro Dalcin } 28898613b67SLisandro Dalcin 289aa3661deSLisandro Dalcin if (version == 1) { 290aa3661deSLisandro Dalcin ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 29198613b67SLisandro Dalcin ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 2929c6ac3b3SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 293aa3661deSLisandro Dalcin } else if (version == 2) { 294e32f2f54SBarry Smith if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 29582a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 296aa3661deSLisandro Dalcin ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr); 297aa3661deSLisandro Dalcin #else 298e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)"); 299aa3661deSLisandro Dalcin #endif 300a8248277SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2"); 301aa3661deSLisandro Dalcin 302aa3661deSLisandro Dalcin ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr); 303d3462f78SMatthew Knepley if (hasOperator) { 304aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 305aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 306aa3661deSLisandro Dalcin ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 307aa3661deSLisandro Dalcin } else { 308aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 309aa3661deSLisandro Dalcin provided preconditioner matrix with the default matrix free version. */ 3106cab3a1bSJed Brown void *functx; 3116cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 3126cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr); 313aa3661deSLisandro Dalcin /* Force no preconditioner */ 314aa3661deSLisandro Dalcin ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 315aa3661deSLisandro Dalcin ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 316251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr); 317aa3661deSLisandro Dalcin if (!match) { 318aa3661deSLisandro Dalcin ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 319aa3661deSLisandro Dalcin ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 320aa3661deSLisandro Dalcin } 321aa3661deSLisandro Dalcin } 3226bf464f9SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 323aa3661deSLisandro Dalcin PetscFunctionReturn(0); 324aa3661deSLisandro Dalcin } 325aa3661deSLisandro Dalcin 3264a2ae208SSatish Balay #undef __FUNCT__ 327dfe15315SJed Brown #define __FUNCT__ "DMRestrictHook_SNESVecSol" 328dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx) 329dfe15315SJed Brown { 330dfe15315SJed Brown SNES snes = (SNES)ctx; 331dfe15315SJed Brown PetscErrorCode ierr; 332dfe15315SJed Brown Vec Xfine,Xfine_named = PETSC_NULL,Xcoarse; 333dfe15315SJed Brown 334dfe15315SJed Brown PetscFunctionBegin; 335dfe15315SJed Brown if (dmfine == snes->dm) Xfine = snes->vec_sol; 336dfe15315SJed Brown else { 337dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr); 338dfe15315SJed Brown Xfine = Xfine_named; 339dfe15315SJed Brown } 340dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 341dfe15315SJed Brown ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr); 342dfe15315SJed Brown ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr); 343dfe15315SJed Brown ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 344dfe15315SJed Brown if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);} 345dfe15315SJed Brown PetscFunctionReturn(0); 346dfe15315SJed Brown } 347dfe15315SJed Brown 348dfe15315SJed Brown #undef __FUNCT__ 349caa4e7f2SJed Brown #define __FUNCT__ "KSPComputeOperators_SNES" 350a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can 351a6950cb2SJed Brown * safely call SNESGetDM() in their residual evaluation routine. */ 352caa4e7f2SJed Brown static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,MatStructure *mstruct,void *ctx) 353caa4e7f2SJed Brown { 354caa4e7f2SJed Brown SNES snes = (SNES)ctx; 355caa4e7f2SJed Brown PetscErrorCode ierr; 356caa4e7f2SJed Brown Mat Asave = A,Bsave = B; 357dfe15315SJed Brown Vec X,Xnamed = PETSC_NULL; 358dfe15315SJed Brown DM dmsave; 359caa4e7f2SJed Brown 360caa4e7f2SJed Brown PetscFunctionBegin; 361dfe15315SJed Brown dmsave = snes->dm; 362dfe15315SJed Brown ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr); 363dfe15315SJed Brown if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */ 364dfe15315SJed Brown else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ 365dfe15315SJed Brown ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 366dfe15315SJed Brown X = Xnamed; 367dfe15315SJed Brown } 368dfe15315SJed Brown ierr = SNESComputeJacobian(snes,X,&A,&B,mstruct);CHKERRQ(ierr); 369caa4e7f2SJed Brown if (A != Asave || B != Bsave) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"No support for changing matrices at this time"); 370dfe15315SJed Brown if (Xnamed) { 371dfe15315SJed Brown ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 372dfe15315SJed Brown } 373dfe15315SJed Brown snes->dm = dmsave; 374caa4e7f2SJed Brown PetscFunctionReturn(0); 375caa4e7f2SJed Brown } 376caa4e7f2SJed Brown 377caa4e7f2SJed Brown #undef __FUNCT__ 3786cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices" 3796cab3a1bSJed Brown /*@ 3806cab3a1bSJed Brown SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX() 3816cab3a1bSJed Brown 3826cab3a1bSJed Brown Collective 3836cab3a1bSJed Brown 3846cab3a1bSJed Brown Input Arguments: 3856cab3a1bSJed Brown . snes - snes to configure 3866cab3a1bSJed Brown 3876cab3a1bSJed Brown Level: developer 3886cab3a1bSJed Brown 3896cab3a1bSJed Brown .seealso: SNESSetUp() 3906cab3a1bSJed Brown @*/ 3916cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes) 3926cab3a1bSJed Brown { 3936cab3a1bSJed Brown PetscErrorCode ierr; 3946cab3a1bSJed Brown DM dm; 3956cab3a1bSJed Brown SNESDM sdm; 3966cab3a1bSJed Brown 3976cab3a1bSJed Brown PetscFunctionBegin; 3986cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3996cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 400caa4e7f2SJed Brown if (!sdm->computejacobian) { 40117842b4fSJed Brown SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_PLIB,"SNESDM not improperly configured"); 4026cab3a1bSJed Brown } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) { 4036cab3a1bSJed Brown Mat J; 4046cab3a1bSJed Brown void *functx; 4056cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4066cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4076cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4086cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 4096cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr); 4106cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 411caa4e7f2SJed Brown } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 4126cab3a1bSJed Brown Mat J,B; 4136cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4146cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4156cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4166cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 41706f20277SJed Brown /* sdm->computejacobian was already set to reach here */ 41806f20277SJed Brown ierr = SNESSetJacobian(snes,J,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 4196cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 4206cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 421caa4e7f2SJed Brown } else if (!snes->jacobian_pre) { 4226cab3a1bSJed Brown Mat J,B; 4236cab3a1bSJed Brown J = snes->jacobian; 4246cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 4256cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 4266cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 4276cab3a1bSJed Brown } 428caa4e7f2SJed Brown { 42960a3618bSJed Brown PetscBool flg = PETSC_FALSE; 430caa4e7f2SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_kspcompute",&flg,PETSC_NULL);CHKERRQ(ierr); 431caa4e7f2SJed Brown if (flg) { /* Plan to transition to this model */ 432caa4e7f2SJed Brown KSP ksp; 433caa4e7f2SJed Brown ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 434caa4e7f2SJed Brown ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr); 435dfe15315SJed Brown ierr = DMCoarsenHookAdd(snes->dm,PETSC_NULL,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 436caa4e7f2SJed Brown } 437caa4e7f2SJed Brown } 4386cab3a1bSJed Brown PetscFunctionReturn(0); 4396cab3a1bSJed Brown } 4406cab3a1bSJed Brown 4416cab3a1bSJed Brown #undef __FUNCT__ 4424a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions" 4439b94acceSBarry Smith /*@ 44494b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 4459b94acceSBarry Smith 446c7afd0dbSLois Curfman McInnes Collective on SNES 447c7afd0dbSLois Curfman McInnes 4489b94acceSBarry Smith Input Parameter: 4499b94acceSBarry Smith . snes - the SNES context 4509b94acceSBarry Smith 45136851e7fSLois Curfman McInnes Options Database Keys: 452ea630c6eSPeter Brune + -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas 45382738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 45482738288SBarry Smith of the change in the solution between steps 45570441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 456b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 457b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 458b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 4594839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 460ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 461a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 462e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 463b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 4642492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 46582738288SBarry Smith solver; hence iterations will continue until max_it 4661fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 46782738288SBarry Smith of convergence test 468e8105e01SRichard Katz . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 469e8105e01SRichard Katz filename given prints to stdout 470a6570f20SBarry Smith . -snes_monitor_solution - plots solution at each iteration 471a6570f20SBarry Smith . -snes_monitor_residual - plots residual (not its norm) at each iteration 472a6570f20SBarry Smith . -snes_monitor_solution_update - plots update to solution at each iteration 473a6570f20SBarry Smith . -snes_monitor_draw - plots residual norm at each iteration 474e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 4755968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 476fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 47782738288SBarry Smith 47882738288SBarry Smith Options Database for Eisenstat-Walker method: 479fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 4804b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 48136851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 48236851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 48336851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 48436851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 48536851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 48636851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 48782738288SBarry Smith 48811ca99fdSLois Curfman McInnes Notes: 48911ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 4900598bfebSBarry Smith the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>. 49183e2fdc7SBarry Smith 49236851e7fSLois Curfman McInnes Level: beginner 49336851e7fSLois Curfman McInnes 4949b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 4959b94acceSBarry Smith 49669ed319cSSatish Balay .seealso: SNESSetOptionsPrefix() 4979b94acceSBarry Smith @*/ 4987087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 4999b94acceSBarry Smith { 500872b6db9SPeter Brune PetscBool flg,mf,mf_operator,pcset; 501efd51863SBarry Smith PetscInt i,indx,lag,mf_version,grids; 502aa3661deSLisandro Dalcin MatStructure matflag; 50385385478SLisandro Dalcin const char *deft = SNESLS; 50485385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 50585385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 506e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 507649052a6SBarry Smith PetscViewer monviewer; 50885385478SLisandro Dalcin PetscErrorCode ierr; 509a64e098fSPeter Brune const char *optionsprefix; 5109b94acceSBarry Smith 5113a40ed3dSBarry Smith PetscFunctionBegin; 5120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 513ca161407SBarry Smith 514186905e3SBarry Smith if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 5153194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 5167adad957SLisandro Dalcin if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; } 517b0a32e0cSBarry Smith ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 518d64ed03dSBarry Smith if (flg) { 519186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 5207adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 521186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 522d64ed03dSBarry Smith } 52390d69ab7SBarry Smith /* not used here, but called so will go into help messaage */ 524909c8a9fSBarry Smith ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 52593c39befSBarry Smith 526c60f73f4SPeter Brune ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr); 52757034d6fSHong Zhang ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 528186905e3SBarry Smith 52957034d6fSHong Zhang ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 530b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 531b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 53224254dc1SJed Brown ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 533ddf469c8SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr); 534acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr); 53585385478SLisandro Dalcin 536a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 537a8054027SBarry Smith if (flg) { 538a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 539a8054027SBarry Smith } 540e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 541e35cf81dSBarry Smith if (flg) { 542e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 543e35cf81dSBarry Smith } 544efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 545efd51863SBarry Smith if (flg) { 546efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 547efd51863SBarry Smith } 548a8054027SBarry Smith 54985385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 55085385478SLisandro Dalcin if (flg) { 55185385478SLisandro Dalcin switch (indx) { 5527f7931b9SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 5537f7931b9SBarry Smith case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 55485385478SLisandro Dalcin } 55585385478SLisandro Dalcin } 55685385478SLisandro Dalcin 557acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr); 558186905e3SBarry Smith 559fdacfa88SPeter Brune ierr = PetscOptionsEList("-snes_norm_type","SNES Norm type","SNESSetNormType",SNESNormTypes,5,"function",&indx,&flg);CHKERRQ(ierr); 560fdacfa88SPeter Brune if (flg) { ierr = SNESSetNormType(snes,(SNESNormType)indx);CHKERRQ(ierr); } 561fdacfa88SPeter Brune 56285385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 56385385478SLisandro Dalcin 564acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 565186905e3SBarry Smith 566fa9f3622SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 567fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 568fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 569fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 570fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 571fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 572fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 573186905e3SBarry Smith 57490d69ab7SBarry Smith flg = PETSC_FALSE; 575acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 576a6570f20SBarry Smith if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 577eabae89aSBarry Smith 578a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 579e8105e01SRichard Katz if (flg) { 580649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 581649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 582e8105e01SRichard Katz } 583eabae89aSBarry Smith 584b271bb04SBarry Smith ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 585b271bb04SBarry Smith if (flg) { 586b271bb04SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 587b271bb04SBarry Smith } 588b271bb04SBarry Smith 589a6570f20SBarry Smith ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 590eabae89aSBarry Smith if (flg) { 591649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 592f1bef1bcSMatthew Knepley ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 593e8105e01SRichard Katz } 594eabae89aSBarry Smith 595a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 596eabae89aSBarry Smith if (flg) { 597649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 598649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 599eabae89aSBarry Smith } 600eabae89aSBarry Smith 6015180491cSLisandro Dalcin ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 6025180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 6035180491cSLisandro Dalcin 60490d69ab7SBarry Smith flg = PETSC_FALSE; 605acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 606a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 60790d69ab7SBarry Smith flg = PETSC_FALSE; 608acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 609a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 61090d69ab7SBarry Smith flg = PETSC_FALSE; 611acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 612a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 61390d69ab7SBarry Smith flg = PETSC_FALSE; 614acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 615a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 61690d69ab7SBarry Smith flg = PETSC_FALSE; 617acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 618b271bb04SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 619e24b481bSBarry Smith 62090d69ab7SBarry Smith flg = PETSC_FALSE; 621acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 6224b27c08aSLois Curfman McInnes if (flg) { 6236cab3a1bSJed Brown void *functx; 6246cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 6256cab3a1bSJed Brown ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr); 626ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 6279b94acceSBarry Smith } 628639f9d9dSBarry Smith 629aa3661deSLisandro Dalcin mf = mf_operator = PETSC_FALSE; 630aa3661deSLisandro Dalcin flg = PETSC_FALSE; 631acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr); 632a8248277SBarry Smith if (flg && mf_operator) { 633a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 634a8248277SBarry Smith mf = PETSC_TRUE; 635a8248277SBarry Smith } 636aa3661deSLisandro Dalcin flg = PETSC_FALSE; 637acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr); 638aa3661deSLisandro Dalcin if (!flg && mf_operator) mf = PETSC_TRUE; 639aa3661deSLisandro Dalcin mf_version = 1; 640aa3661deSLisandro Dalcin ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr); 641aa3661deSLisandro Dalcin 642d28543b3SPeter Brune 64389b92e6fSPeter Brune /* GS Options */ 64489b92e6fSPeter Brune ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr); 64589b92e6fSPeter Brune 64676b2cf59SMatthew Knepley for(i = 0; i < numberofsetfromoptions; i++) { 64776b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 64876b2cf59SMatthew Knepley } 64976b2cf59SMatthew Knepley 650e7788613SBarry Smith if (snes->ops->setfromoptions) { 651e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 652639f9d9dSBarry Smith } 6535d973c19SBarry Smith 6545d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 6555d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 656b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 6574bbc92c1SBarry Smith 658aa3661deSLisandro Dalcin if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 6591cee3971SBarry Smith 6601cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 661aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 662aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 66385385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 66493993e2dSLois Curfman McInnes 6659e764e56SPeter Brune if (!snes->linesearch) { 666f1c6b773SPeter Brune ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 6679e764e56SPeter Brune } 668f1c6b773SPeter Brune ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr); 6699e764e56SPeter Brune 67051e86f29SPeter Brune /* if someone has set the SNES PC type, create it. */ 67151e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 67251e86f29SPeter Brune ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 67351e86f29SPeter Brune if (pcset && (!snes->pc)) { 67451e86f29SPeter Brune ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr); 67551e86f29SPeter Brune } 6763a40ed3dSBarry Smith PetscFunctionReturn(0); 6779b94acceSBarry Smith } 6789b94acceSBarry Smith 679d25893d9SBarry Smith #undef __FUNCT__ 680d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 681d25893d9SBarry Smith /*@ 682d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 683d25893d9SBarry Smith the nonlinear solvers. 684d25893d9SBarry Smith 685d25893d9SBarry Smith Logically Collective on SNES 686d25893d9SBarry Smith 687d25893d9SBarry Smith Input Parameters: 688d25893d9SBarry Smith + snes - the SNES context 689d25893d9SBarry Smith . compute - function to compute the context 690d25893d9SBarry Smith - destroy - function to destroy the context 691d25893d9SBarry Smith 692d25893d9SBarry Smith Level: intermediate 693d25893d9SBarry Smith 694d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 695d25893d9SBarry Smith 696d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 697d25893d9SBarry Smith @*/ 698d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 699d25893d9SBarry Smith { 700d25893d9SBarry Smith PetscFunctionBegin; 701d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 702d25893d9SBarry Smith snes->ops->usercompute = compute; 703d25893d9SBarry Smith snes->ops->userdestroy = destroy; 704d25893d9SBarry Smith PetscFunctionReturn(0); 705d25893d9SBarry Smith } 706a847f771SSatish Balay 7074a2ae208SSatish Balay #undef __FUNCT__ 7084a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 709b07ff414SBarry Smith /*@ 7109b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 7119b94acceSBarry Smith the nonlinear solvers. 7129b94acceSBarry Smith 7133f9fe445SBarry Smith Logically Collective on SNES 714fee21e36SBarry Smith 715c7afd0dbSLois Curfman McInnes Input Parameters: 716c7afd0dbSLois Curfman McInnes + snes - the SNES context 717c7afd0dbSLois Curfman McInnes - usrP - optional user context 718c7afd0dbSLois Curfman McInnes 71936851e7fSLois Curfman McInnes Level: intermediate 72036851e7fSLois Curfman McInnes 7219b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 7229b94acceSBarry Smith 723ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext() 7249b94acceSBarry Smith @*/ 7257087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 7269b94acceSBarry Smith { 7271b2093e4SBarry Smith PetscErrorCode ierr; 728b07ff414SBarry Smith KSP ksp; 7291b2093e4SBarry Smith 7303a40ed3dSBarry Smith PetscFunctionBegin; 7310700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 732b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 733b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 7349b94acceSBarry Smith snes->user = usrP; 7353a40ed3dSBarry Smith PetscFunctionReturn(0); 7369b94acceSBarry Smith } 73774679c65SBarry Smith 7384a2ae208SSatish Balay #undef __FUNCT__ 7394a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 740b07ff414SBarry Smith /*@ 7419b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 7429b94acceSBarry Smith nonlinear solvers. 7439b94acceSBarry Smith 744c7afd0dbSLois Curfman McInnes Not Collective 745c7afd0dbSLois Curfman McInnes 7469b94acceSBarry Smith Input Parameter: 7479b94acceSBarry Smith . snes - SNES context 7489b94acceSBarry Smith 7499b94acceSBarry Smith Output Parameter: 7509b94acceSBarry Smith . usrP - user context 7519b94acceSBarry Smith 75236851e7fSLois Curfman McInnes Level: intermediate 75336851e7fSLois Curfman McInnes 7549b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 7559b94acceSBarry Smith 7569b94acceSBarry Smith .seealso: SNESSetApplicationContext() 7579b94acceSBarry Smith @*/ 758e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 7599b94acceSBarry Smith { 7603a40ed3dSBarry Smith PetscFunctionBegin; 7610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 762e71120c6SJed Brown *(void**)usrP = snes->user; 7633a40ed3dSBarry Smith PetscFunctionReturn(0); 7649b94acceSBarry Smith } 76574679c65SBarry Smith 7664a2ae208SSatish Balay #undef __FUNCT__ 7674a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 7689b94acceSBarry Smith /*@ 769c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 770c8228a4eSBarry Smith at this time. 7719b94acceSBarry Smith 772c7afd0dbSLois Curfman McInnes Not Collective 773c7afd0dbSLois Curfman McInnes 7749b94acceSBarry Smith Input Parameter: 7759b94acceSBarry Smith . snes - SNES context 7769b94acceSBarry Smith 7779b94acceSBarry Smith Output Parameter: 7789b94acceSBarry Smith . iter - iteration number 7799b94acceSBarry Smith 780c8228a4eSBarry Smith Notes: 781c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 782c8228a4eSBarry Smith 783c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 78408405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 78508405cd6SLois Curfman McInnes .vb 78608405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 78708405cd6SLois Curfman McInnes if (!(it % 2)) { 78808405cd6SLois Curfman McInnes [compute Jacobian here] 78908405cd6SLois Curfman McInnes } 79008405cd6SLois Curfman McInnes .ve 791c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 79208405cd6SLois Curfman McInnes recomputed every second SNES iteration. 793c8228a4eSBarry Smith 79436851e7fSLois Curfman McInnes Level: intermediate 79536851e7fSLois Curfman McInnes 7962b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 7972b668275SBarry Smith 798b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 7999b94acceSBarry Smith @*/ 8007087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 8019b94acceSBarry Smith { 8023a40ed3dSBarry Smith PetscFunctionBegin; 8030700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8044482741eSBarry Smith PetscValidIntPointer(iter,2); 8059b94acceSBarry Smith *iter = snes->iter; 8063a40ed3dSBarry Smith PetscFunctionReturn(0); 8079b94acceSBarry Smith } 80874679c65SBarry Smith 8094a2ae208SSatish Balay #undef __FUNCT__ 810360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber" 811360c497dSPeter Brune /*@ 812360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 813360c497dSPeter Brune 814360c497dSPeter Brune Not Collective 815360c497dSPeter Brune 816360c497dSPeter Brune Input Parameter: 817360c497dSPeter Brune . snes - SNES context 818360c497dSPeter Brune . iter - iteration number 819360c497dSPeter Brune 820360c497dSPeter Brune Level: developer 821360c497dSPeter Brune 822360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number, 823360c497dSPeter Brune 824360c497dSPeter Brune .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 825360c497dSPeter Brune @*/ 826360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 827360c497dSPeter Brune { 828360c497dSPeter Brune PetscErrorCode ierr; 829360c497dSPeter Brune 830360c497dSPeter Brune PetscFunctionBegin; 831360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 832360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 833360c497dSPeter Brune snes->iter = iter; 834360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 835360c497dSPeter Brune PetscFunctionReturn(0); 836360c497dSPeter Brune } 837360c497dSPeter Brune 838360c497dSPeter Brune #undef __FUNCT__ 8394a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 8409b94acceSBarry Smith /*@ 8419b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 8429b94acceSBarry Smith with SNESSSetFunction(). 8439b94acceSBarry Smith 844c7afd0dbSLois Curfman McInnes Collective on SNES 845c7afd0dbSLois Curfman McInnes 8469b94acceSBarry Smith Input Parameter: 8479b94acceSBarry Smith . snes - SNES context 8489b94acceSBarry Smith 8499b94acceSBarry Smith Output Parameter: 8509b94acceSBarry Smith . fnorm - 2-norm of function 8519b94acceSBarry Smith 85236851e7fSLois Curfman McInnes Level: intermediate 85336851e7fSLois Curfman McInnes 8549b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 855a86d99e1SLois Curfman McInnes 856b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 8579b94acceSBarry Smith @*/ 8587087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 8599b94acceSBarry Smith { 8603a40ed3dSBarry Smith PetscFunctionBegin; 8610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8624482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 8639b94acceSBarry Smith *fnorm = snes->norm; 8643a40ed3dSBarry Smith PetscFunctionReturn(0); 8659b94acceSBarry Smith } 86674679c65SBarry Smith 867360c497dSPeter Brune 868360c497dSPeter Brune #undef __FUNCT__ 869360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm" 870360c497dSPeter Brune /*@ 871360c497dSPeter Brune SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm(). 872360c497dSPeter Brune 873360c497dSPeter Brune Collective on SNES 874360c497dSPeter Brune 875360c497dSPeter Brune Input Parameter: 876360c497dSPeter Brune . snes - SNES context 877360c497dSPeter Brune . fnorm - 2-norm of function 878360c497dSPeter Brune 879360c497dSPeter Brune Level: developer 880360c497dSPeter Brune 881360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm 882360c497dSPeter Brune 883360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm(). 884360c497dSPeter Brune @*/ 885360c497dSPeter Brune PetscErrorCode SNESSetFunctionNorm(SNES snes,PetscReal fnorm) 886360c497dSPeter Brune { 887360c497dSPeter Brune 888360c497dSPeter Brune PetscErrorCode ierr; 889360c497dSPeter Brune 890360c497dSPeter Brune PetscFunctionBegin; 891360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 892360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 893360c497dSPeter Brune snes->norm = fnorm; 894360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 895360c497dSPeter Brune PetscFunctionReturn(0); 896360c497dSPeter Brune } 897360c497dSPeter Brune 8984a2ae208SSatish Balay #undef __FUNCT__ 899b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 9009b94acceSBarry Smith /*@ 901b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 9029b94acceSBarry Smith attempted by the nonlinear solver. 9039b94acceSBarry Smith 904c7afd0dbSLois Curfman McInnes Not Collective 905c7afd0dbSLois Curfman McInnes 9069b94acceSBarry Smith Input Parameter: 9079b94acceSBarry Smith . snes - SNES context 9089b94acceSBarry Smith 9099b94acceSBarry Smith Output Parameter: 9109b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 9119b94acceSBarry Smith 912c96a6f78SLois Curfman McInnes Notes: 913c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 914c96a6f78SLois Curfman McInnes 91536851e7fSLois Curfman McInnes Level: intermediate 91636851e7fSLois Curfman McInnes 9179b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 91858ebbce7SBarry Smith 919e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 92058ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 9219b94acceSBarry Smith @*/ 9227087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 9239b94acceSBarry Smith { 9243a40ed3dSBarry Smith PetscFunctionBegin; 9250700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9264482741eSBarry Smith PetscValidIntPointer(nfails,2); 92750ffb88aSMatthew Knepley *nfails = snes->numFailures; 92850ffb88aSMatthew Knepley PetscFunctionReturn(0); 92950ffb88aSMatthew Knepley } 93050ffb88aSMatthew Knepley 93150ffb88aSMatthew Knepley #undef __FUNCT__ 932b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 93350ffb88aSMatthew Knepley /*@ 934b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 93550ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 93650ffb88aSMatthew Knepley 93750ffb88aSMatthew Knepley Not Collective 93850ffb88aSMatthew Knepley 93950ffb88aSMatthew Knepley Input Parameters: 94050ffb88aSMatthew Knepley + snes - SNES context 94150ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 94250ffb88aSMatthew Knepley 94350ffb88aSMatthew Knepley Level: intermediate 94450ffb88aSMatthew Knepley 94550ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 94658ebbce7SBarry Smith 947e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 94858ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 94950ffb88aSMatthew Knepley @*/ 9507087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 95150ffb88aSMatthew Knepley { 95250ffb88aSMatthew Knepley PetscFunctionBegin; 9530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 95450ffb88aSMatthew Knepley snes->maxFailures = maxFails; 95550ffb88aSMatthew Knepley PetscFunctionReturn(0); 95650ffb88aSMatthew Knepley } 95750ffb88aSMatthew Knepley 95850ffb88aSMatthew Knepley #undef __FUNCT__ 959b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 96050ffb88aSMatthew Knepley /*@ 961b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 96250ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 96350ffb88aSMatthew Knepley 96450ffb88aSMatthew Knepley Not Collective 96550ffb88aSMatthew Knepley 96650ffb88aSMatthew Knepley Input Parameter: 96750ffb88aSMatthew Knepley . snes - SNES context 96850ffb88aSMatthew Knepley 96950ffb88aSMatthew Knepley Output Parameter: 97050ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 97150ffb88aSMatthew Knepley 97250ffb88aSMatthew Knepley Level: intermediate 97350ffb88aSMatthew Knepley 97450ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 97558ebbce7SBarry Smith 976e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 97758ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 97858ebbce7SBarry Smith 97950ffb88aSMatthew Knepley @*/ 9807087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 98150ffb88aSMatthew Knepley { 98250ffb88aSMatthew Knepley PetscFunctionBegin; 9830700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9844482741eSBarry Smith PetscValidIntPointer(maxFails,2); 98550ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 9863a40ed3dSBarry Smith PetscFunctionReturn(0); 9879b94acceSBarry Smith } 988a847f771SSatish Balay 9894a2ae208SSatish Balay #undef __FUNCT__ 9902541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 9912541af92SBarry Smith /*@ 9922541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 9932541af92SBarry Smith done by SNES. 9942541af92SBarry Smith 9952541af92SBarry Smith Not Collective 9962541af92SBarry Smith 9972541af92SBarry Smith Input Parameter: 9982541af92SBarry Smith . snes - SNES context 9992541af92SBarry Smith 10002541af92SBarry Smith Output Parameter: 10012541af92SBarry Smith . nfuncs - number of evaluations 10022541af92SBarry Smith 10032541af92SBarry Smith Level: intermediate 10042541af92SBarry Smith 10052541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 100658ebbce7SBarry Smith 1007e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 10082541af92SBarry Smith @*/ 10097087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 10102541af92SBarry Smith { 10112541af92SBarry Smith PetscFunctionBegin; 10120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10132541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 10142541af92SBarry Smith *nfuncs = snes->nfuncs; 10152541af92SBarry Smith PetscFunctionReturn(0); 10162541af92SBarry Smith } 10172541af92SBarry Smith 10182541af92SBarry Smith #undef __FUNCT__ 10193d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 10203d4c4710SBarry Smith /*@ 10213d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 10223d4c4710SBarry Smith linear solvers. 10233d4c4710SBarry Smith 10243d4c4710SBarry Smith Not Collective 10253d4c4710SBarry Smith 10263d4c4710SBarry Smith Input Parameter: 10273d4c4710SBarry Smith . snes - SNES context 10283d4c4710SBarry Smith 10293d4c4710SBarry Smith Output Parameter: 10303d4c4710SBarry Smith . nfails - number of failed solves 10313d4c4710SBarry Smith 10323d4c4710SBarry Smith Notes: 10333d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 10343d4c4710SBarry Smith 10353d4c4710SBarry Smith Level: intermediate 10363d4c4710SBarry Smith 10373d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 103858ebbce7SBarry Smith 1039e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 10403d4c4710SBarry Smith @*/ 10417087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 10423d4c4710SBarry Smith { 10433d4c4710SBarry Smith PetscFunctionBegin; 10440700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10453d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 10463d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 10473d4c4710SBarry Smith PetscFunctionReturn(0); 10483d4c4710SBarry Smith } 10493d4c4710SBarry Smith 10503d4c4710SBarry Smith #undef __FUNCT__ 10513d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 10523d4c4710SBarry Smith /*@ 10533d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 10543d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 10553d4c4710SBarry Smith 10563f9fe445SBarry Smith Logically Collective on SNES 10573d4c4710SBarry Smith 10583d4c4710SBarry Smith Input Parameters: 10593d4c4710SBarry Smith + snes - SNES context 10603d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 10613d4c4710SBarry Smith 10623d4c4710SBarry Smith Level: intermediate 10633d4c4710SBarry Smith 1064a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 10653d4c4710SBarry Smith 10663d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 10673d4c4710SBarry Smith 106858ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 10693d4c4710SBarry Smith @*/ 10707087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 10713d4c4710SBarry Smith { 10723d4c4710SBarry Smith PetscFunctionBegin; 10730700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1074c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 10753d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 10763d4c4710SBarry Smith PetscFunctionReturn(0); 10773d4c4710SBarry Smith } 10783d4c4710SBarry Smith 10793d4c4710SBarry Smith #undef __FUNCT__ 10803d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 10813d4c4710SBarry Smith /*@ 10823d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 10833d4c4710SBarry Smith are allowed before SNES terminates 10843d4c4710SBarry Smith 10853d4c4710SBarry Smith Not Collective 10863d4c4710SBarry Smith 10873d4c4710SBarry Smith Input Parameter: 10883d4c4710SBarry Smith . snes - SNES context 10893d4c4710SBarry Smith 10903d4c4710SBarry Smith Output Parameter: 10913d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 10923d4c4710SBarry Smith 10933d4c4710SBarry Smith Level: intermediate 10943d4c4710SBarry Smith 10953d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 10963d4c4710SBarry Smith 10973d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 10983d4c4710SBarry Smith 1099e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 11003d4c4710SBarry Smith @*/ 11017087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 11023d4c4710SBarry Smith { 11033d4c4710SBarry Smith PetscFunctionBegin; 11040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11053d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 11063d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 11073d4c4710SBarry Smith PetscFunctionReturn(0); 11083d4c4710SBarry Smith } 11093d4c4710SBarry Smith 11103d4c4710SBarry Smith #undef __FUNCT__ 1111b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 1112c96a6f78SLois Curfman McInnes /*@ 1113b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1114c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1115c96a6f78SLois Curfman McInnes 1116c7afd0dbSLois Curfman McInnes Not Collective 1117c7afd0dbSLois Curfman McInnes 1118c96a6f78SLois Curfman McInnes Input Parameter: 1119c96a6f78SLois Curfman McInnes . snes - SNES context 1120c96a6f78SLois Curfman McInnes 1121c96a6f78SLois Curfman McInnes Output Parameter: 1122c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1123c96a6f78SLois Curfman McInnes 1124c96a6f78SLois Curfman McInnes Notes: 1125c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1126c96a6f78SLois Curfman McInnes 112736851e7fSLois Curfman McInnes Level: intermediate 112836851e7fSLois Curfman McInnes 1129c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 11302b668275SBarry Smith 11318c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 1132c96a6f78SLois Curfman McInnes @*/ 11337087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 1134c96a6f78SLois Curfman McInnes { 11353a40ed3dSBarry Smith PetscFunctionBegin; 11360700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11374482741eSBarry Smith PetscValidIntPointer(lits,2); 1138c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 11393a40ed3dSBarry Smith PetscFunctionReturn(0); 1140c96a6f78SLois Curfman McInnes } 1141c96a6f78SLois Curfman McInnes 11424a2ae208SSatish Balay #undef __FUNCT__ 114394b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 114452baeb72SSatish Balay /*@ 114594b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 11469b94acceSBarry Smith 114794b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 1148c7afd0dbSLois Curfman McInnes 11499b94acceSBarry Smith Input Parameter: 11509b94acceSBarry Smith . snes - the SNES context 11519b94acceSBarry Smith 11529b94acceSBarry Smith Output Parameter: 115394b7f48cSBarry Smith . ksp - the KSP context 11549b94acceSBarry Smith 11559b94acceSBarry Smith Notes: 115694b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 11579b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 11582999313aSBarry Smith PC contexts as well. 11599b94acceSBarry Smith 116036851e7fSLois Curfman McInnes Level: beginner 116136851e7fSLois Curfman McInnes 116294b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 11639b94acceSBarry Smith 11642999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 11659b94acceSBarry Smith @*/ 11667087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 11679b94acceSBarry Smith { 11681cee3971SBarry Smith PetscErrorCode ierr; 11691cee3971SBarry Smith 11703a40ed3dSBarry Smith PetscFunctionBegin; 11710700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11724482741eSBarry Smith PetscValidPointer(ksp,2); 11731cee3971SBarry Smith 11741cee3971SBarry Smith if (!snes->ksp) { 11751cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 11761cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 11771cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 11781cee3971SBarry Smith } 117994b7f48cSBarry Smith *ksp = snes->ksp; 11803a40ed3dSBarry Smith PetscFunctionReturn(0); 11819b94acceSBarry Smith } 118282bf6240SBarry Smith 11834a2ae208SSatish Balay #undef __FUNCT__ 11842999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 11852999313aSBarry Smith /*@ 11862999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 11872999313aSBarry Smith 11882999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 11892999313aSBarry Smith 11902999313aSBarry Smith Input Parameters: 11912999313aSBarry Smith + snes - the SNES context 11922999313aSBarry Smith - ksp - the KSP context 11932999313aSBarry Smith 11942999313aSBarry Smith Notes: 11952999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 11962999313aSBarry Smith so this routine is rarely needed. 11972999313aSBarry Smith 11982999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 11992999313aSBarry Smith decreased by one. 12002999313aSBarry Smith 12012999313aSBarry Smith Level: developer 12022999313aSBarry Smith 12032999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 12042999313aSBarry Smith 12052999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 12062999313aSBarry Smith @*/ 12077087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 12082999313aSBarry Smith { 12092999313aSBarry Smith PetscErrorCode ierr; 12102999313aSBarry Smith 12112999313aSBarry Smith PetscFunctionBegin; 12120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12130700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 12142999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 12157dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1216906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 12172999313aSBarry Smith snes->ksp = ksp; 12182999313aSBarry Smith PetscFunctionReturn(0); 12192999313aSBarry Smith } 12202999313aSBarry Smith 12217adad957SLisandro Dalcin #if 0 12222999313aSBarry Smith #undef __FUNCT__ 12234a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 12246849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1225e24b481bSBarry Smith { 1226e24b481bSBarry Smith PetscFunctionBegin; 1227e24b481bSBarry Smith PetscFunctionReturn(0); 1228e24b481bSBarry Smith } 12297adad957SLisandro Dalcin #endif 1230e24b481bSBarry Smith 12319b94acceSBarry Smith /* -----------------------------------------------------------*/ 12324a2ae208SSatish Balay #undef __FUNCT__ 12334a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 123452baeb72SSatish Balay /*@ 12359b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 12369b94acceSBarry Smith 1237c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1238c7afd0dbSLois Curfman McInnes 1239c7afd0dbSLois Curfman McInnes Input Parameters: 1240906ed7ccSBarry Smith . comm - MPI communicator 12419b94acceSBarry Smith 12429b94acceSBarry Smith Output Parameter: 12439b94acceSBarry Smith . outsnes - the new SNES context 12449b94acceSBarry Smith 1245c7afd0dbSLois Curfman McInnes Options Database Keys: 1246c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1247c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1248c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1249c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1250c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1251c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1252c1f60f51SBarry Smith 125336851e7fSLois Curfman McInnes Level: beginner 125436851e7fSLois Curfman McInnes 12559b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 12569b94acceSBarry Smith 1257a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1258a8054027SBarry Smith 12599b94acceSBarry Smith @*/ 12607087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 12619b94acceSBarry Smith { 1262dfbe8321SBarry Smith PetscErrorCode ierr; 12639b94acceSBarry Smith SNES snes; 1264fa9f3622SBarry Smith SNESKSPEW *kctx; 126537fcc0dbSBarry Smith 12663a40ed3dSBarry Smith PetscFunctionBegin; 1267ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 12688ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 12698ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 12708ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 12718ba1e511SMatthew Knepley #endif 12728ba1e511SMatthew Knepley 12733194b578SJed Brown ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 12747adad957SLisandro Dalcin 127585385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 12762c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 127788976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 12789b94acceSBarry Smith snes->max_its = 50; 12799750a799SBarry Smith snes->max_funcs = 10000; 12809b94acceSBarry Smith snes->norm = 0.0; 1281fdacfa88SPeter Brune snes->normtype = SNES_NORM_FUNCTION; 1282b4874afaSBarry Smith snes->rtol = 1.e-8; 1283b4874afaSBarry Smith snes->ttol = 0.0; 128470441072SBarry Smith snes->abstol = 1.e-50; 1285c60f73f4SPeter Brune snes->stol = 1.e-8; 12864b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 12879b94acceSBarry Smith snes->nfuncs = 0; 128850ffb88aSMatthew Knepley snes->numFailures = 0; 128950ffb88aSMatthew Knepley snes->maxFailures = 1; 12907a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1291e35cf81dSBarry Smith snes->lagjacobian = 1; 1292a8054027SBarry Smith snes->lagpreconditioner = 1; 1293639f9d9dSBarry Smith snes->numbermonitors = 0; 12949b94acceSBarry Smith snes->data = 0; 12954dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1296186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 12976f24a144SLois Curfman McInnes snes->nwork = 0; 129858c9b817SLisandro Dalcin snes->work = 0; 129958c9b817SLisandro Dalcin snes->nvwork = 0; 130058c9b817SLisandro Dalcin snes->vwork = 0; 1301758f92a0SBarry Smith snes->conv_hist_len = 0; 1302758f92a0SBarry Smith snes->conv_hist_max = 0; 1303758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1304758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1305758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1306e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1307e4ed7901SPeter Brune snes->norm_init = 0.; 1308e4ed7901SPeter Brune snes->norm_init_set = PETSC_FALSE; 1309184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 131089b92e6fSPeter Brune snes->gssweeps = 1; 13119b94acceSBarry Smith 13123d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 13133d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 13143d4c4710SBarry Smith 13159b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 131638f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 13179b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 13189b94acceSBarry Smith kctx->version = 2; 13199b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 13209b94acceSBarry Smith this was too large for some test cases */ 132175567043SBarry Smith kctx->rtol_last = 0.0; 13229b94acceSBarry Smith kctx->rtol_max = .9; 13239b94acceSBarry Smith kctx->gamma = 1.0; 132462d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 132571f87433Sdalcinl kctx->alpha2 = kctx->alpha; 13269b94acceSBarry Smith kctx->threshold = .1; 132775567043SBarry Smith kctx->lresid_last = 0.0; 132875567043SBarry Smith kctx->norm_last = 0.0; 13299b94acceSBarry Smith 13309b94acceSBarry Smith *outsnes = snes; 13313a40ed3dSBarry Smith PetscFunctionReturn(0); 13329b94acceSBarry Smith } 13339b94acceSBarry Smith 13344a2ae208SSatish Balay #undef __FUNCT__ 13354a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 13369b94acceSBarry Smith /*@C 13379b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 13389b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 13399b94acceSBarry Smith equations. 13409b94acceSBarry Smith 13413f9fe445SBarry Smith Logically Collective on SNES 1342fee21e36SBarry Smith 1343c7afd0dbSLois Curfman McInnes Input Parameters: 1344c7afd0dbSLois Curfman McInnes + snes - the SNES context 1345c7afd0dbSLois Curfman McInnes . r - vector to store function value 1346de044059SHong Zhang . func - function evaluation routine 1347c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1348c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 13499b94acceSBarry Smith 1350c7afd0dbSLois Curfman McInnes Calling sequence of func: 13518d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1352c7afd0dbSLois Curfman McInnes 1353c586c404SJed Brown + snes - the SNES context 1354c586c404SJed Brown . x - state at which to evaluate residual 1355c586c404SJed Brown . f - vector to put residual 1356c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 13579b94acceSBarry Smith 13589b94acceSBarry Smith Notes: 13599b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 13609b94acceSBarry Smith $ f'(x) x = -f(x), 1361c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 13629b94acceSBarry Smith 136336851e7fSLois Curfman McInnes Level: beginner 136436851e7fSLois Curfman McInnes 13659b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 13669b94acceSBarry Smith 13678b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard() 13689b94acceSBarry Smith @*/ 13697087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 13709b94acceSBarry Smith { 137185385478SLisandro Dalcin PetscErrorCode ierr; 13726cab3a1bSJed Brown DM dm; 13736cab3a1bSJed Brown 13743a40ed3dSBarry Smith PetscFunctionBegin; 13750700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1376d2a683ecSLisandro Dalcin if (r) { 1377d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1378d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 137985385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 13806bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 138185385478SLisandro Dalcin snes->vec_func = r; 1382d2a683ecSLisandro Dalcin } 13836cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 13846cab3a1bSJed Brown ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr); 13853a40ed3dSBarry Smith PetscFunctionReturn(0); 13869b94acceSBarry Smith } 13879b94acceSBarry Smith 1388646217ecSPeter Brune 1389646217ecSPeter Brune #undef __FUNCT__ 1390e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction" 1391e4ed7901SPeter Brune /*@C 1392e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1393e4ed7901SPeter Brune function norm at the initialization of the method. In some 1394e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1395e4ed7901SPeter Brune SNESSolve. This function allows one to avoid a redundant call 1396e4ed7901SPeter Brune to SNESComputeFunction in that case. 1397e4ed7901SPeter Brune 1398e4ed7901SPeter Brune Logically Collective on SNES 1399e4ed7901SPeter Brune 1400e4ed7901SPeter Brune Input Parameters: 1401e4ed7901SPeter Brune + snes - the SNES context 1402e4ed7901SPeter Brune - f - vector to store function value 1403e4ed7901SPeter Brune 1404e4ed7901SPeter Brune Notes: 1405e4ed7901SPeter Brune This should not be modified during the solution procedure. 1406e4ed7901SPeter Brune 1407e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1408e4ed7901SPeter Brune 1409e4ed7901SPeter Brune Level: developer 1410e4ed7901SPeter Brune 1411e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function 1412e4ed7901SPeter Brune 1413e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm() 1414e4ed7901SPeter Brune @*/ 1415e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1416e4ed7901SPeter Brune { 1417e4ed7901SPeter Brune PetscErrorCode ierr; 1418e4ed7901SPeter Brune Vec vec_func; 1419e4ed7901SPeter Brune 1420e4ed7901SPeter Brune PetscFunctionBegin; 1421e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1422e4ed7901SPeter Brune PetscValidHeaderSpecific(f,VEC_CLASSID,2); 1423e4ed7901SPeter Brune PetscCheckSameComm(snes,1,f,2); 1424e4ed7901SPeter Brune ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1425e4ed7901SPeter Brune ierr = VecCopy(f, vec_func);CHKERRQ(ierr); 1426217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 1427e4ed7901SPeter Brune PetscFunctionReturn(0); 1428e4ed7901SPeter Brune } 1429e4ed7901SPeter Brune 1430e4ed7901SPeter Brune 1431e4ed7901SPeter Brune #undef __FUNCT__ 1432e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm" 1433e4ed7901SPeter Brune /*@C 1434e4ed7901SPeter Brune SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm 1435e4ed7901SPeter Brune at the initialization of the method. In some instances, the user has precomputed 1436e4ed7901SPeter Brune the function and its norm before calling SNESSolve. This function allows one to 1437e4ed7901SPeter Brune avoid a redundant call to SNESComputeFunction() and VecNorm() in that case. 1438e4ed7901SPeter Brune 1439e4ed7901SPeter Brune Logically Collective on SNES 1440e4ed7901SPeter Brune 1441e4ed7901SPeter Brune Input Parameters: 1442e4ed7901SPeter Brune + snes - the SNES context 1443e4ed7901SPeter Brune - fnorm - the norm of F as set by SNESSetInitialFunction() 1444e4ed7901SPeter Brune 1445e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1446e4ed7901SPeter Brune 1447e4ed7901SPeter Brune Level: developer 1448e4ed7901SPeter Brune 1449e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm 1450e4ed7901SPeter Brune 1451e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction() 1452e4ed7901SPeter Brune @*/ 1453e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm) 1454e4ed7901SPeter Brune { 1455e4ed7901SPeter Brune PetscFunctionBegin; 1456e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1457e4ed7901SPeter Brune snes->norm_init = fnorm; 1458e4ed7901SPeter Brune snes->norm_init_set = PETSC_TRUE; 1459e4ed7901SPeter Brune PetscFunctionReturn(0); 1460e4ed7901SPeter Brune } 1461e4ed7901SPeter Brune 1462e4ed7901SPeter Brune #undef __FUNCT__ 1463534ebe21SPeter Brune #define __FUNCT__ "SNESSetNormType" 1464534ebe21SPeter Brune /*@ 1465534ebe21SPeter Brune SNESSetNormType - Sets the SNESNormType used in covergence and monitoring 1466534ebe21SPeter Brune of the SNES method. 1467534ebe21SPeter Brune 1468534ebe21SPeter Brune Logically Collective on SNES 1469534ebe21SPeter Brune 1470534ebe21SPeter Brune Input Parameters: 1471534ebe21SPeter Brune + snes - the SNES context 1472534ebe21SPeter Brune - normtype - the type of the norm used 1473534ebe21SPeter Brune 1474534ebe21SPeter Brune Notes: 1475534ebe21SPeter Brune Only certain SNES methods support certain SNESNormTypes. Most require evaluation 1476534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1477534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1478534ebe21SPeter Brune (SNESGS) and the like do not require the norm of the function to be computed, and therfore 1479534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1480534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1481534ebe21SPeter Brune their solution. 1482534ebe21SPeter Brune 1483534ebe21SPeter Brune Level: developer 1484534ebe21SPeter Brune 1485534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1486534ebe21SPeter Brune 1487534ebe21SPeter Brune .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType 1488534ebe21SPeter Brune @*/ 1489534ebe21SPeter Brune PetscErrorCode SNESSetNormType(SNES snes, SNESNormType normtype) 1490534ebe21SPeter Brune { 1491534ebe21SPeter Brune PetscFunctionBegin; 1492534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1493534ebe21SPeter Brune snes->normtype = normtype; 1494534ebe21SPeter Brune PetscFunctionReturn(0); 1495534ebe21SPeter Brune } 1496534ebe21SPeter Brune 1497534ebe21SPeter Brune 1498534ebe21SPeter Brune #undef __FUNCT__ 1499534ebe21SPeter Brune #define __FUNCT__ "SNESGetNormType" 1500534ebe21SPeter Brune /*@ 1501534ebe21SPeter Brune SNESGetNormType - Gets the SNESNormType used in covergence and monitoring 1502534ebe21SPeter Brune of the SNES method. 1503534ebe21SPeter Brune 1504534ebe21SPeter Brune Logically Collective on SNES 1505534ebe21SPeter Brune 1506534ebe21SPeter Brune Input Parameters: 1507534ebe21SPeter Brune + snes - the SNES context 1508534ebe21SPeter Brune - normtype - the type of the norm used 1509534ebe21SPeter Brune 1510534ebe21SPeter Brune Level: advanced 1511534ebe21SPeter Brune 1512534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1513534ebe21SPeter Brune 1514534ebe21SPeter Brune .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType 1515534ebe21SPeter Brune @*/ 1516534ebe21SPeter Brune PetscErrorCode SNESGetNormType(SNES snes, SNESNormType *normtype) 1517534ebe21SPeter Brune { 1518534ebe21SPeter Brune PetscFunctionBegin; 1519534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1520534ebe21SPeter Brune *normtype = snes->normtype; 1521534ebe21SPeter Brune PetscFunctionReturn(0); 1522534ebe21SPeter Brune } 1523534ebe21SPeter Brune 1524534ebe21SPeter Brune #undef __FUNCT__ 1525646217ecSPeter Brune #define __FUNCT__ "SNESSetGS" 1526c79ef259SPeter Brune /*@C 1527c79ef259SPeter Brune SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for 1528c79ef259SPeter Brune use with composed nonlinear solvers. 1529c79ef259SPeter Brune 1530c79ef259SPeter Brune Input Parameters: 1531c79ef259SPeter Brune + snes - the SNES context 1532c79ef259SPeter Brune . gsfunc - function evaluation routine 1533c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 1534c79ef259SPeter Brune smoother evaluation routine (may be PETSC_NULL) 1535c79ef259SPeter Brune 1536c79ef259SPeter Brune Calling sequence of func: 1537c79ef259SPeter Brune $ func (SNES snes,Vec x,Vec b,void *ctx); 1538c79ef259SPeter Brune 1539c79ef259SPeter Brune + X - solution vector 1540c79ef259SPeter Brune . B - RHS vector 1541d28543b3SPeter Brune - ctx - optional user-defined Gauss-Seidel context 1542c79ef259SPeter Brune 1543c79ef259SPeter Brune Notes: 1544c79ef259SPeter Brune The GS routines are used by the composed nonlinear solver to generate 1545c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1546c79ef259SPeter Brune 1547d28543b3SPeter Brune Level: intermediate 1548c79ef259SPeter Brune 1549d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1550c79ef259SPeter Brune 1551c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS() 1552c79ef259SPeter Brune @*/ 15536cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx) 15546cab3a1bSJed Brown { 15556cab3a1bSJed Brown PetscErrorCode ierr; 15566cab3a1bSJed Brown DM dm; 15576cab3a1bSJed Brown 1558646217ecSPeter Brune PetscFunctionBegin; 15596cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15606cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 15616cab3a1bSJed Brown ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr); 1562646217ecSPeter Brune PetscFunctionReturn(0); 1563646217ecSPeter Brune } 1564646217ecSPeter Brune 1565d25893d9SBarry Smith #undef __FUNCT__ 156689b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps" 156789b92e6fSPeter Brune /*@ 156889b92e6fSPeter Brune SNESSetGSSweeps - Sets the number of sweeps of GS to use. 156989b92e6fSPeter Brune 157089b92e6fSPeter Brune Input Parameters: 157189b92e6fSPeter Brune + snes - the SNES context 157289b92e6fSPeter Brune - sweeps - the number of sweeps of GS to perform. 157389b92e6fSPeter Brune 157489b92e6fSPeter Brune Level: intermediate 157589b92e6fSPeter Brune 157689b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 157789b92e6fSPeter Brune 157889b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps() 157989b92e6fSPeter Brune @*/ 158089b92e6fSPeter Brune 158189b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) { 158289b92e6fSPeter Brune PetscFunctionBegin; 158389b92e6fSPeter Brune snes->gssweeps = sweeps; 158489b92e6fSPeter Brune PetscFunctionReturn(0); 158589b92e6fSPeter Brune } 158689b92e6fSPeter Brune 158789b92e6fSPeter Brune 158889b92e6fSPeter Brune #undef __FUNCT__ 158989b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps" 159089b92e6fSPeter Brune /*@ 159189b92e6fSPeter Brune SNESGetGSSweeps - Gets the number of sweeps GS will use. 159289b92e6fSPeter Brune 159389b92e6fSPeter Brune Input Parameters: 159489b92e6fSPeter Brune . snes - the SNES context 159589b92e6fSPeter Brune 159689b92e6fSPeter Brune Output Parameters: 159789b92e6fSPeter Brune . sweeps - the number of sweeps of GS to perform. 159889b92e6fSPeter Brune 159989b92e6fSPeter Brune Level: intermediate 160089b92e6fSPeter Brune 160189b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 160289b92e6fSPeter Brune 160389b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps() 160489b92e6fSPeter Brune @*/ 160589b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) { 160689b92e6fSPeter Brune PetscFunctionBegin; 160789b92e6fSPeter Brune *sweeps = snes->gssweeps; 160889b92e6fSPeter Brune PetscFunctionReturn(0); 160989b92e6fSPeter Brune } 161089b92e6fSPeter Brune 161189b92e6fSPeter Brune #undef __FUNCT__ 16128b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 16138b0a5094SBarry Smith PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 16148b0a5094SBarry Smith { 16158b0a5094SBarry Smith PetscErrorCode ierr; 1616*e03ab78fSPeter Brune DM dm; 1617*e03ab78fSPeter Brune SNESDM sdm; 16186cab3a1bSJed Brown 16198b0a5094SBarry Smith PetscFunctionBegin; 1620*e03ab78fSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1621*e03ab78fSPeter Brune ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 16228b0a5094SBarry Smith /* A(x)*x - b(x) */ 1623*e03ab78fSPeter Brune if (sdm->computepfunction) { 1624*e03ab78fSPeter Brune ierr = (*sdm->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr); 1625*e03ab78fSPeter Brune } else if (snes->dm) { 1626*e03ab78fSPeter Brune ierr = DMComputeFunction(snes->dm,x,f);CHKERRQ(ierr); 1627*e03ab78fSPeter Brune } else { 1628*e03ab78fSPeter Brune SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() or SNESSetDM() before SNESPicardComputeFunction to provide Picard function."); 1629*e03ab78fSPeter Brune } 1630*e03ab78fSPeter Brune 1631*e03ab78fSPeter Brune if (sdm->computepjacobian) { 1632*e03ab78fSPeter Brune ierr = (*sdm->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,sdm->pctx);CHKERRQ(ierr); 1633*e03ab78fSPeter Brune } else if (snes->dm) { 1634*e03ab78fSPeter Brune ierr = DMComputeJacobian(snes->dm,x,snes->jacobian,snes->jacobian_pre,&snes->matstruct);CHKERRQ(ierr); 1635*e03ab78fSPeter Brune } else { 1636*e03ab78fSPeter Brune SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() or SNESSetDM() before SNESPicardComputeFunction to provide Picard matrix."); 1637*e03ab78fSPeter Brune } 1638*e03ab78fSPeter Brune 16398b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 16408b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 16418b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 16428b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 16438b0a5094SBarry Smith PetscFunctionReturn(0); 16448b0a5094SBarry Smith } 16458b0a5094SBarry Smith 16468b0a5094SBarry Smith #undef __FUNCT__ 16478b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 16488b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 16498b0a5094SBarry Smith { 16508b0a5094SBarry Smith PetscFunctionBegin; 1651*e03ab78fSPeter Brune /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */ 16528b0a5094SBarry Smith *flag = snes->matstruct; 16538b0a5094SBarry Smith PetscFunctionReturn(0); 16548b0a5094SBarry Smith } 16558b0a5094SBarry Smith 16568b0a5094SBarry Smith #undef __FUNCT__ 16578b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 16588b0a5094SBarry Smith /*@C 16590d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 16608b0a5094SBarry Smith 16618b0a5094SBarry Smith Logically Collective on SNES 16628b0a5094SBarry Smith 16638b0a5094SBarry Smith Input Parameters: 16648b0a5094SBarry Smith + snes - the SNES context 16658b0a5094SBarry Smith . r - vector to store function value 16668b0a5094SBarry Smith . func - function evaluation routine 16678b0a5094SBarry Smith . jmat - normally the same as mat but you can pass another matrix for which you compute the Jacobian of A(x) x - b(x) (see jmat below) 16688b0a5094SBarry Smith . mat - matrix to store A 16698b0a5094SBarry Smith . mfunc - function to compute matrix value 16708b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 16718b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 16728b0a5094SBarry Smith 16738b0a5094SBarry Smith Calling sequence of func: 16748b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 16758b0a5094SBarry Smith 16768b0a5094SBarry Smith + f - function vector 16778b0a5094SBarry Smith - ctx - optional user-defined function context 16788b0a5094SBarry Smith 16798b0a5094SBarry Smith Calling sequence of mfunc: 16808b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 16818b0a5094SBarry Smith 16828b0a5094SBarry Smith + x - input vector 16838b0a5094SBarry Smith . jmat - Form Jacobian matrix of A(x) x - b(x) if available, not there is really no reason to use it in this way since then you can just use SNESSetJacobian(), 16848b0a5094SBarry Smith normally just pass mat in this location 16858b0a5094SBarry Smith . mat - form A(x) matrix 16868b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 16878b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 16888b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 16898b0a5094SBarry Smith 16908b0a5094SBarry Smith Notes: 16918b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 16928b0a5094SBarry Smith 16938b0a5094SBarry Smith $ Solves the equation A(x) x = b(x) via the defect correction algorithm A(x^{n}) (x^{n+1} - x^{n}) = b(x^{n}) - A(x^{n})x^{n} 16948b0a5094SBarry Smith $ Note that when an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = b(x^{n}) iteration. 16958b0a5094SBarry Smith 16968b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 16978b0a5094SBarry Smith 16980d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 16990d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 17008b0a5094SBarry Smith 17018b0a5094SBarry Smith There is some controversity over the definition of a Picard iteration for nonlinear systems but almost everyone agrees that it involves a linear solve and some 17028b0a5094SBarry Smith believe it is the iteration A(x^{n}) x^{n+1} = b(x^{n}) hence we use the name Picard. If anyone has an authoritative reference that defines the Picard iteration 17038b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 17048b0a5094SBarry Smith 17058b0a5094SBarry Smith Level: beginner 17068b0a5094SBarry Smith 17078b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 17088b0a5094SBarry Smith 17090d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard() 17108b0a5094SBarry Smith @*/ 17118b0a5094SBarry Smith PetscErrorCode SNESSetPicard(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),Mat jmat, Mat mat, PetscErrorCode (*mfunc)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 17128b0a5094SBarry Smith { 17138b0a5094SBarry Smith PetscErrorCode ierr; 1714*e03ab78fSPeter Brune DM dm; 1715*e03ab78fSPeter Brune 17168b0a5094SBarry Smith PetscFunctionBegin; 17178b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1718*e03ab78fSPeter Brune ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 1719*e03ab78fSPeter Brune ierr = DMSNESSetPicard(dm,func,mfunc,ctx);CHKERRQ(ierr); 17208b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 17218b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 17228b0a5094SBarry Smith PetscFunctionReturn(0); 17238b0a5094SBarry Smith } 17248b0a5094SBarry Smith 17258b0a5094SBarry Smith #undef __FUNCT__ 1726d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1727d25893d9SBarry Smith /*@C 1728d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1729d25893d9SBarry Smith 1730d25893d9SBarry Smith Logically Collective on SNES 1731d25893d9SBarry Smith 1732d25893d9SBarry Smith Input Parameters: 1733d25893d9SBarry Smith + snes - the SNES context 1734d25893d9SBarry Smith . func - function evaluation routine 1735d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1736d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1737d25893d9SBarry Smith 1738d25893d9SBarry Smith Calling sequence of func: 1739d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1740d25893d9SBarry Smith 1741d25893d9SBarry Smith . f - function vector 1742d25893d9SBarry Smith - ctx - optional user-defined function context 1743d25893d9SBarry Smith 1744d25893d9SBarry Smith Level: intermediate 1745d25893d9SBarry Smith 1746d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1747d25893d9SBarry Smith 1748d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1749d25893d9SBarry Smith @*/ 1750d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1751d25893d9SBarry Smith { 1752d25893d9SBarry Smith PetscFunctionBegin; 1753d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1754d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1755d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1756d25893d9SBarry Smith PetscFunctionReturn(0); 1757d25893d9SBarry Smith } 1758d25893d9SBarry Smith 17593ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 17603ab0aad5SBarry Smith #undef __FUNCT__ 17611096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 17621096aae1SMatthew Knepley /*@C 17631096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 17641096aae1SMatthew Knepley it assumes a zero right hand side. 17651096aae1SMatthew Knepley 17663f9fe445SBarry Smith Logically Collective on SNES 17671096aae1SMatthew Knepley 17681096aae1SMatthew Knepley Input Parameter: 17691096aae1SMatthew Knepley . snes - the SNES context 17701096aae1SMatthew Knepley 17711096aae1SMatthew Knepley Output Parameter: 1772bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 17731096aae1SMatthew Knepley 17741096aae1SMatthew Knepley Level: intermediate 17751096aae1SMatthew Knepley 17761096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 17771096aae1SMatthew Knepley 177885385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 17791096aae1SMatthew Knepley @*/ 17807087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 17811096aae1SMatthew Knepley { 17821096aae1SMatthew Knepley PetscFunctionBegin; 17830700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 17841096aae1SMatthew Knepley PetscValidPointer(rhs,2); 178585385478SLisandro Dalcin *rhs = snes->vec_rhs; 17861096aae1SMatthew Knepley PetscFunctionReturn(0); 17871096aae1SMatthew Knepley } 17881096aae1SMatthew Knepley 17891096aae1SMatthew Knepley #undef __FUNCT__ 17904a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 17919b94acceSBarry Smith /*@ 179236851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 17939b94acceSBarry Smith SNESSetFunction(). 17949b94acceSBarry Smith 1795c7afd0dbSLois Curfman McInnes Collective on SNES 1796c7afd0dbSLois Curfman McInnes 17979b94acceSBarry Smith Input Parameters: 1798c7afd0dbSLois Curfman McInnes + snes - the SNES context 1799c7afd0dbSLois Curfman McInnes - x - input vector 18009b94acceSBarry Smith 18019b94acceSBarry Smith Output Parameter: 18023638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 18039b94acceSBarry Smith 18041bffabb2SLois Curfman McInnes Notes: 180536851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 180636851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 180736851e7fSLois Curfman McInnes themselves. 180836851e7fSLois Curfman McInnes 180936851e7fSLois Curfman McInnes Level: developer 181036851e7fSLois Curfman McInnes 18119b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 18129b94acceSBarry Smith 1813a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 18149b94acceSBarry Smith @*/ 18157087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 18169b94acceSBarry Smith { 1817dfbe8321SBarry Smith PetscErrorCode ierr; 18186cab3a1bSJed Brown DM dm; 18196cab3a1bSJed Brown SNESDM sdm; 18209b94acceSBarry Smith 18213a40ed3dSBarry Smith PetscFunctionBegin; 18220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 18230700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 18240700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1825c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1826c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 18274ec14c9cSBarry Smith VecValidValues(x,2,PETSC_TRUE); 1828184914b5SBarry Smith 18296cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18306cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 1831d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 18326cab3a1bSJed Brown if (sdm->computefunction) { 1833d64ed03dSBarry Smith PetscStackPush("SNES user function"); 18346cab3a1bSJed Brown ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 1835d64ed03dSBarry Smith PetscStackPop; 183673250ac0SBarry Smith } else if (snes->dm) { 1837644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1838c90fad12SPeter Brune } else if (snes->vec_rhs) { 1839c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1840644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 184185385478SLisandro Dalcin if (snes->vec_rhs) { 184285385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 18433ab0aad5SBarry Smith } 1844ae3c334cSLois Curfman McInnes snes->nfuncs++; 1845d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 18464ec14c9cSBarry Smith VecValidValues(y,3,PETSC_FALSE); 18473a40ed3dSBarry Smith PetscFunctionReturn(0); 18489b94acceSBarry Smith } 18499b94acceSBarry Smith 18504a2ae208SSatish Balay #undef __FUNCT__ 1851646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1852c79ef259SPeter Brune /*@ 1853c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1854c79ef259SPeter Brune SNESSetGS(). 1855c79ef259SPeter Brune 1856c79ef259SPeter Brune Collective on SNES 1857c79ef259SPeter Brune 1858c79ef259SPeter Brune Input Parameters: 1859c79ef259SPeter Brune + snes - the SNES context 1860c79ef259SPeter Brune . x - input vector 1861c79ef259SPeter Brune - b - rhs vector 1862c79ef259SPeter Brune 1863c79ef259SPeter Brune Output Parameter: 1864c79ef259SPeter Brune . x - new solution vector 1865c79ef259SPeter Brune 1866c79ef259SPeter Brune Notes: 1867c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1868c79ef259SPeter Brune implementations, so most users would not generally call this routine 1869c79ef259SPeter Brune themselves. 1870c79ef259SPeter Brune 1871c79ef259SPeter Brune Level: developer 1872c79ef259SPeter Brune 1873c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1874c79ef259SPeter Brune 1875c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1876c79ef259SPeter Brune @*/ 1877646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1878646217ecSPeter Brune { 1879646217ecSPeter Brune PetscErrorCode ierr; 188089b92e6fSPeter Brune PetscInt i; 18816cab3a1bSJed Brown DM dm; 18826cab3a1bSJed Brown SNESDM sdm; 1883646217ecSPeter Brune 1884646217ecSPeter Brune PetscFunctionBegin; 1885646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1886646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1887646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1888646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 1889646217ecSPeter Brune if(b) PetscCheckSameComm(snes,1,b,3); 18904ec14c9cSBarry Smith if (b) VecValidValues(b,2,PETSC_TRUE); 1891701cf23dSPeter Brune ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 18926cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18936cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 18946cab3a1bSJed Brown if (sdm->computegs) { 189589b92e6fSPeter Brune for (i = 0; i < snes->gssweeps; i++) { 1896646217ecSPeter Brune PetscStackPush("SNES user GS"); 18976cab3a1bSJed Brown ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 1898646217ecSPeter Brune PetscStackPop; 189989b92e6fSPeter Brune } 1900646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 1901701cf23dSPeter Brune ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 19024ec14c9cSBarry Smith VecValidValues(x,3,PETSC_FALSE); 1903646217ecSPeter Brune PetscFunctionReturn(0); 1904646217ecSPeter Brune } 1905646217ecSPeter Brune 1906646217ecSPeter Brune 1907646217ecSPeter Brune #undef __FUNCT__ 19084a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 190962fef451SLois Curfman McInnes /*@ 191062fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 191162fef451SLois Curfman McInnes set with SNESSetJacobian(). 191262fef451SLois Curfman McInnes 1913c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1914c7afd0dbSLois Curfman McInnes 191562fef451SLois Curfman McInnes Input Parameters: 1916c7afd0dbSLois Curfman McInnes + snes - the SNES context 1917c7afd0dbSLois Curfman McInnes - x - input vector 191862fef451SLois Curfman McInnes 191962fef451SLois Curfman McInnes Output Parameters: 1920c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 192162fef451SLois Curfman McInnes . B - optional preconditioning matrix 19222b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1923fee21e36SBarry Smith 1924e35cf81dSBarry Smith Options Database Keys: 1925e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1926693365a8SJed Brown . -snes_lag_jacobian <lag> 1927693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1928693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1929693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 19304c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1931c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 1932c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 1933c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 1934c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 1935c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 19364c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 1937c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 1938c01495d3SJed Brown 1939e35cf81dSBarry Smith 194062fef451SLois Curfman McInnes Notes: 194162fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 194262fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 194362fef451SLois Curfman McInnes 194494b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1945dc5a77f8SLois Curfman McInnes flag parameter. 194662fef451SLois Curfman McInnes 194736851e7fSLois Curfman McInnes Level: developer 194836851e7fSLois Curfman McInnes 194962fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 195062fef451SLois Curfman McInnes 1951e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 195262fef451SLois Curfman McInnes @*/ 19537087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 19549b94acceSBarry Smith { 1955dfbe8321SBarry Smith PetscErrorCode ierr; 1956ace3abfcSBarry Smith PetscBool flag; 19576cab3a1bSJed Brown DM dm; 19586cab3a1bSJed Brown SNESDM sdm; 19593a40ed3dSBarry Smith 19603a40ed3dSBarry Smith PetscFunctionBegin; 19610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 19620700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 19634482741eSBarry Smith PetscValidPointer(flg,5); 1964c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 19654ec14c9cSBarry Smith VecValidValues(X,2,PETSC_TRUE); 19666cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 19676cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 19686cab3a1bSJed Brown if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 1969ebd3b9afSBarry Smith 1970ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1971ebd3b9afSBarry Smith 1972fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 1973fe3ffe1eSBarry Smith snes->lagjacobian = -1; 1974fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1975fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 1976e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1977e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1978251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1979ebd3b9afSBarry Smith if (flag) { 1980ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1981ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1982ebd3b9afSBarry Smith } 1983e35cf81dSBarry Smith PetscFunctionReturn(0); 1984e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1985e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1986e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1987251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1988ebd3b9afSBarry Smith if (flag) { 1989ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1990ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1991ebd3b9afSBarry Smith } 1992e35cf81dSBarry Smith PetscFunctionReturn(0); 1993e35cf81dSBarry Smith } 1994e35cf81dSBarry Smith 1995c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 1996e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1997d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 19986cab3a1bSJed Brown ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr); 1999d64ed03dSBarry Smith PetscStackPop; 2000d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 2001a8054027SBarry Smith 20023b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 20033b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 20043b4f5425SBarry Smith snes->lagpreconditioner = -1; 20053b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 2006a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 2007a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 2008a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 2009a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 2010a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 2011a8054027SBarry Smith } 2012a8054027SBarry Smith 20136d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 20140700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 20150700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 2016693365a8SJed Brown { 2017693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 2018693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 2019693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 2020693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 2021693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 2022693365a8SJed Brown if (flag || flag_draw || flag_contour) { 2023693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 2024693365a8SJed Brown MatStructure mstruct; 2025693365a8SJed Brown PetscViewer vdraw,vstdout; 20266b3a5b13SJed Brown PetscBool flg; 2027693365a8SJed Brown if (flag_operator) { 2028693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 2029693365a8SJed Brown Bexp = Bexp_mine; 2030693365a8SJed Brown } else { 2031693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 2032251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 2033693365a8SJed Brown if (flg) Bexp = *B; 2034693365a8SJed Brown else { 2035693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 2036693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 2037693365a8SJed Brown Bexp = Bexp_mine; 2038693365a8SJed Brown } 2039693365a8SJed Brown } 2040693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 2041693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 2042693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 2043693365a8SJed Brown if (flag_draw || flag_contour) { 2044693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2045693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 2046693365a8SJed Brown } else vdraw = PETSC_NULL; 2047693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 2048693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 2049693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 2050693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 2051693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2052693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 2053693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2054693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 2055693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2056693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 2057693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2058693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 2059693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2060693365a8SJed Brown } 2061693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2062693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2063693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 2064693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 2065693365a8SJed Brown } 2066693365a8SJed Brown } 20674c30e9fbSJed Brown { 20686719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 20696719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 20704c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 20716719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 20724c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 20734c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 20746719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 20756719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 20766719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 20776719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 20784c30e9fbSJed Brown Mat Bfd; 20794c30e9fbSJed Brown MatStructure mstruct; 20804c30e9fbSJed Brown PetscViewer vdraw,vstdout; 20814c30e9fbSJed Brown ISColoring iscoloring; 20824c30e9fbSJed Brown MatFDColoring matfdcoloring; 20834c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 20844c30e9fbSJed Brown void *funcctx; 20856719d8e4SJed Brown PetscReal norm1,norm2,normmax; 20864c30e9fbSJed Brown 20874c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 20884c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 20894c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 20904c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 20914c30e9fbSJed Brown 20924c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 20934c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 20944c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 20954c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 20964c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 20974c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 20984c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 20994c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 21004c30e9fbSJed Brown 21014c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 21024c30e9fbSJed Brown if (flag_draw || flag_contour) { 21034c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 21044c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 21054c30e9fbSJed Brown } else vdraw = PETSC_NULL; 21064c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 21076719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 21084c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 21094c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 21106719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 21114c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 21124c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 21134c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 21146719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 21154c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 21166719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 21176719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 21184c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 21194c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 21204c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 21214c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 21224c30e9fbSJed Brown } 21234c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 21246719d8e4SJed Brown 21256719d8e4SJed Brown if (flag_threshold) { 21266719d8e4SJed Brown PetscInt bs,rstart,rend,i; 21276719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 21286719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 21296719d8e4SJed Brown for (i=rstart; i<rend; i++) { 21306719d8e4SJed Brown const PetscScalar *ba,*ca; 21316719d8e4SJed Brown const PetscInt *bj,*cj; 21326719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 21336719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 21346719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 21356719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 21366719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 21376719d8e4SJed Brown for (j=0; j<bn; j++) { 21386719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 21396719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 21406719d8e4SJed Brown maxentrycol = bj[j]; 21416719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 21426719d8e4SJed Brown } 21436719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 21446719d8e4SJed Brown maxdiffcol = bj[j]; 21456719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 21466719d8e4SJed Brown } 21476719d8e4SJed Brown if (rdiff > maxrdiff) { 21486719d8e4SJed Brown maxrdiffcol = bj[j]; 21496719d8e4SJed Brown maxrdiff = rdiff; 21506719d8e4SJed Brown } 21516719d8e4SJed Brown } 21526719d8e4SJed Brown if (maxrdiff > 1) { 21536719d8e4SJed 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); 21546719d8e4SJed Brown for (j=0; j<bn; j++) { 21556719d8e4SJed Brown PetscReal rdiff; 21566719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 21576719d8e4SJed Brown if (rdiff > 1) { 21586719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 21596719d8e4SJed Brown } 21606719d8e4SJed Brown } 21616719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 21626719d8e4SJed Brown } 21636719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 21646719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 21656719d8e4SJed Brown } 21666719d8e4SJed Brown } 21674c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 21684c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 21694c30e9fbSJed Brown } 21704c30e9fbSJed Brown } 21713a40ed3dSBarry Smith PetscFunctionReturn(0); 21729b94acceSBarry Smith } 21739b94acceSBarry Smith 21744a2ae208SSatish Balay #undef __FUNCT__ 21754a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 21769b94acceSBarry Smith /*@C 21779b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2178044dda88SLois Curfman McInnes location to store the matrix. 21799b94acceSBarry Smith 21803f9fe445SBarry Smith Logically Collective on SNES and Mat 2181c7afd0dbSLois Curfman McInnes 21829b94acceSBarry Smith Input Parameters: 2183c7afd0dbSLois Curfman McInnes + snes - the SNES context 21849b94acceSBarry Smith . A - Jacobian matrix 21859b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 2186efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 2187c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 2188efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 21899b94acceSBarry Smith 21909b94acceSBarry Smith Calling sequence of func: 21918d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 21929b94acceSBarry Smith 2193c7afd0dbSLois Curfman McInnes + x - input vector 21949b94acceSBarry Smith . A - Jacobian matrix 21959b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 2196ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 21972b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 2198c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 21999b94acceSBarry Smith 22009b94acceSBarry Smith Notes: 220194b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 22022cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 2203ac21db08SLois Curfman McInnes 2204ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 22059b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 22069b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 22079b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 22089b94acceSBarry Smith throughout the global iterations. 22099b94acceSBarry Smith 221016913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 221116913363SBarry Smith each matrix. 221216913363SBarry Smith 2213a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 2214a8a26c1eSJed Brown must be a MatFDColoring. 2215a8a26c1eSJed Brown 2216c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2217c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2218c3cc8fd1SJed Brown 221936851e7fSLois Curfman McInnes Level: beginner 222036851e7fSLois Curfman McInnes 22219b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 22229b94acceSBarry Smith 22233ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 22249b94acceSBarry Smith @*/ 22257087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 22269b94acceSBarry Smith { 2227dfbe8321SBarry Smith PetscErrorCode ierr; 22286cab3a1bSJed Brown DM dm; 22293a7fca6bSBarry Smith 22303a40ed3dSBarry Smith PetscFunctionBegin; 22310700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 22320700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 22330700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 2234c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 223506975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 22366cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 22376cab3a1bSJed Brown ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr); 22383a7fca6bSBarry Smith if (A) { 22397dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 22406bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 22419b94acceSBarry Smith snes->jacobian = A; 22423a7fca6bSBarry Smith } 22433a7fca6bSBarry Smith if (B) { 22447dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 22456bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 22469b94acceSBarry Smith snes->jacobian_pre = B; 22473a7fca6bSBarry Smith } 22483a40ed3dSBarry Smith PetscFunctionReturn(0); 22499b94acceSBarry Smith } 225062fef451SLois Curfman McInnes 22514a2ae208SSatish Balay #undef __FUNCT__ 22524a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 2253c2aafc4cSSatish Balay /*@C 2254b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2255b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2256b4fd4287SBarry Smith 2257c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2258c7afd0dbSLois Curfman McInnes 2259b4fd4287SBarry Smith Input Parameter: 2260b4fd4287SBarry Smith . snes - the nonlinear solver context 2261b4fd4287SBarry Smith 2262b4fd4287SBarry Smith Output Parameters: 2263c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 2264b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 226570e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 226670e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 2267fee21e36SBarry Smith 226836851e7fSLois Curfman McInnes Level: advanced 226936851e7fSLois Curfman McInnes 2270b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 2271b4fd4287SBarry Smith @*/ 22727087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 2273b4fd4287SBarry Smith { 22746cab3a1bSJed Brown PetscErrorCode ierr; 22756cab3a1bSJed Brown DM dm; 22766cab3a1bSJed Brown SNESDM sdm; 22776cab3a1bSJed Brown 22783a40ed3dSBarry Smith PetscFunctionBegin; 22790700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2280b4fd4287SBarry Smith if (A) *A = snes->jacobian; 2281b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 22826cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 22836cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 22846cab3a1bSJed Brown if (func) *func = sdm->computejacobian; 22856cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 22863a40ed3dSBarry Smith PetscFunctionReturn(0); 2287b4fd4287SBarry Smith } 2288b4fd4287SBarry Smith 22899b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 22909b94acceSBarry Smith 22914a2ae208SSatish Balay #undef __FUNCT__ 22924a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 22939b94acceSBarry Smith /*@ 22949b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2295272ac6f2SLois Curfman McInnes of a nonlinear solver. 22969b94acceSBarry Smith 2297fee21e36SBarry Smith Collective on SNES 2298fee21e36SBarry Smith 2299c7afd0dbSLois Curfman McInnes Input Parameters: 230070e92668SMatthew Knepley . snes - the SNES context 2301c7afd0dbSLois Curfman McInnes 2302272ac6f2SLois Curfman McInnes Notes: 2303272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2304272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2305272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2306272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2307272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2308272ac6f2SLois Curfman McInnes 230936851e7fSLois Curfman McInnes Level: advanced 231036851e7fSLois Curfman McInnes 23119b94acceSBarry Smith .keywords: SNES, nonlinear, setup 23129b94acceSBarry Smith 23139b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 23149b94acceSBarry Smith @*/ 23157087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 23169b94acceSBarry Smith { 2317dfbe8321SBarry Smith PetscErrorCode ierr; 23186cab3a1bSJed Brown DM dm; 23196cab3a1bSJed Brown SNESDM sdm; 23206e2a1849SPeter Brune SNESLineSearch linesearch; 23216e2a1849SPeter Brune SNESLineSearch pclinesearch; 23226e2a1849SPeter Brune void *lsprectx,*lspostctx; 23236e2a1849SPeter Brune SNESLineSearchPreCheckFunc lsprefunc; 23246e2a1849SPeter Brune SNESLineSearchPostCheckFunc lspostfunc; 23256e2a1849SPeter Brune PetscErrorCode (*func)(SNES,Vec,Vec,void*); 23266e2a1849SPeter Brune Vec f,fpc; 23276e2a1849SPeter Brune void *funcctx; 23286e2a1849SPeter Brune PetscErrorCode (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 23296e2a1849SPeter Brune void *jacctx; 23306e2a1849SPeter Brune Mat A,B; 23313a40ed3dSBarry Smith 23323a40ed3dSBarry Smith PetscFunctionBegin; 23330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23344dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 23359b94acceSBarry Smith 23367adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 233785385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 233885385478SLisandro Dalcin } 233985385478SLisandro Dalcin 2340a63bb30eSJed Brown ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 234117186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 234258c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 234358c9b817SLisandro Dalcin 234458c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 234558c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 234658c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 234758c9b817SLisandro Dalcin } 234858c9b817SLisandro Dalcin 23496cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 23506cab3a1bSJed Brown ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */ 23516cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 23526cab3a1bSJed Brown if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc"); 23536cab3a1bSJed Brown if (!snes->vec_func) { 23546cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2355214df951SJed Brown } 2356efd51863SBarry Smith 2357b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 2358b710008aSBarry Smith 2359f1c6b773SPeter Brune if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);} 23609e764e56SPeter Brune 2361d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 2362d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2363d25893d9SBarry Smith } 2364d25893d9SBarry Smith 23656e2a1849SPeter Brune if (snes->pc) { 23666e2a1849SPeter Brune /* copy the DM over */ 23676e2a1849SPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 23686e2a1849SPeter Brune ierr = SNESSetDM(snes->pc,dm);CHKERRQ(ierr); 23696e2a1849SPeter Brune 23706e2a1849SPeter Brune /* copy the legacy SNES context not related to the DM over*/ 23716e2a1849SPeter Brune ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr); 23726e2a1849SPeter Brune ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr); 23736e2a1849SPeter Brune ierr = SNESSetFunction(snes->pc,fpc,func,funcctx);CHKERRQ(ierr); 23746e2a1849SPeter Brune ierr = SNESGetJacobian(snes,&A,&B,&jac,&jacctx);CHKERRQ(ierr); 23756e2a1849SPeter Brune ierr = SNESSetJacobian(snes->pc,A,B,jac,jacctx);CHKERRQ(ierr); 23766e2a1849SPeter Brune ierr = VecDestroy(&fpc);CHKERRQ(ierr); 23776e2a1849SPeter Brune 23786e2a1849SPeter Brune /* copy the function pointers over */ 23796e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr); 23806e2a1849SPeter Brune 23816e2a1849SPeter Brune /* default to 1 iteration */ 23826e2a1849SPeter Brune ierr = SNESSetTolerances(snes->pc, snes->pc->abstol, snes->pc->rtol, snes->pc->stol, 1, snes->pc->max_funcs);CHKERRQ(ierr); 23836e2a1849SPeter Brune ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); 23846e2a1849SPeter Brune ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 23856e2a1849SPeter Brune 23866e2a1849SPeter Brune /* copy the line search context over */ 23876e2a1849SPeter Brune ierr = SNESGetSNESLineSearch(snes,&linesearch);CHKERRQ(ierr); 23886e2a1849SPeter Brune ierr = SNESGetSNESLineSearch(snes->pc,&pclinesearch);CHKERRQ(ierr); 23896e2a1849SPeter Brune ierr = SNESLineSearchGetPreCheck(linesearch,&lsprefunc,&lsprectx);CHKERRQ(ierr); 23906e2a1849SPeter Brune ierr = SNESLineSearchGetPostCheck(linesearch,&lspostfunc,&lspostctx);CHKERRQ(ierr); 23916e2a1849SPeter Brune ierr = SNESLineSearchSetPreCheck(pclinesearch,lsprefunc,lsprectx);CHKERRQ(ierr); 23926e2a1849SPeter Brune ierr = SNESLineSearchSetPostCheck(pclinesearch,lspostfunc,lspostctx);CHKERRQ(ierr); 23936e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr); 23946e2a1849SPeter Brune } 23956e2a1849SPeter Brune 2396410397dcSLisandro Dalcin if (snes->ops->setup) { 2397410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2398410397dcSLisandro Dalcin } 239958c9b817SLisandro Dalcin 24007aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 24013a40ed3dSBarry Smith PetscFunctionReturn(0); 24029b94acceSBarry Smith } 24039b94acceSBarry Smith 24044a2ae208SSatish Balay #undef __FUNCT__ 240537596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 240637596af1SLisandro Dalcin /*@ 240737596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 240837596af1SLisandro Dalcin 240937596af1SLisandro Dalcin Collective on SNES 241037596af1SLisandro Dalcin 241137596af1SLisandro Dalcin Input Parameter: 241237596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 241337596af1SLisandro Dalcin 2414d25893d9SBarry Smith Level: intermediate 2415d25893d9SBarry Smith 2416d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 241737596af1SLisandro Dalcin 241837596af1SLisandro Dalcin .keywords: SNES, destroy 241937596af1SLisandro Dalcin 242037596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 242137596af1SLisandro Dalcin @*/ 242237596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 242337596af1SLisandro Dalcin { 242437596af1SLisandro Dalcin PetscErrorCode ierr; 242537596af1SLisandro Dalcin 242637596af1SLisandro Dalcin PetscFunctionBegin; 242737596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2428d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2429d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2430d25893d9SBarry Smith snes->user = PETSC_NULL; 2431d25893d9SBarry Smith } 24328a23116dSBarry Smith if (snes->pc) { 24338a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 24348a23116dSBarry Smith } 24358a23116dSBarry Smith 243637596af1SLisandro Dalcin if (snes->ops->reset) { 243737596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 243837596af1SLisandro Dalcin } 24399e764e56SPeter Brune if (snes->ksp) { 24409e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 24419e764e56SPeter Brune } 24429e764e56SPeter Brune 24439e764e56SPeter Brune if (snes->linesearch) { 2444f1c6b773SPeter Brune ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 24459e764e56SPeter Brune } 24469e764e56SPeter Brune 24476bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 24486bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 24496bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 24506bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 24516bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 24526bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2453c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2454c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 245537596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 245637596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 245737596af1SLisandro Dalcin PetscFunctionReturn(0); 245837596af1SLisandro Dalcin } 245937596af1SLisandro Dalcin 246037596af1SLisandro Dalcin #undef __FUNCT__ 24614a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 246252baeb72SSatish Balay /*@ 24639b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 24649b94acceSBarry Smith with SNESCreate(). 24659b94acceSBarry Smith 2466c7afd0dbSLois Curfman McInnes Collective on SNES 2467c7afd0dbSLois Curfman McInnes 24689b94acceSBarry Smith Input Parameter: 24699b94acceSBarry Smith . snes - the SNES context 24709b94acceSBarry Smith 247136851e7fSLois Curfman McInnes Level: beginner 247236851e7fSLois Curfman McInnes 24739b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 24749b94acceSBarry Smith 247563a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 24769b94acceSBarry Smith @*/ 24776bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 24789b94acceSBarry Smith { 24796849ba73SBarry Smith PetscErrorCode ierr; 24803a40ed3dSBarry Smith 24813a40ed3dSBarry Smith PetscFunctionBegin; 24826bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 24836bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 24846bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2485d4bb536fSBarry Smith 24866bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 24878a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 24886b8b9a38SLisandro Dalcin 2489be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 24906bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 24916bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 24926d4c513bSLisandro Dalcin 24936bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 24946bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 2495f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 24966b8b9a38SLisandro Dalcin 24976bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 24986bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 24996bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 25006b8b9a38SLisandro Dalcin } 25016bf464f9SBarry Smith if ((*snes)->conv_malloc) { 25026bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 25036bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 250458c9b817SLisandro Dalcin } 25056bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2506a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 25073a40ed3dSBarry Smith PetscFunctionReturn(0); 25089b94acceSBarry Smith } 25099b94acceSBarry Smith 25109b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 25119b94acceSBarry Smith 25124a2ae208SSatish Balay #undef __FUNCT__ 2513a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2514a8054027SBarry Smith /*@ 2515a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2516a8054027SBarry Smith 25173f9fe445SBarry Smith Logically Collective on SNES 2518a8054027SBarry Smith 2519a8054027SBarry Smith Input Parameters: 2520a8054027SBarry Smith + snes - the SNES context 2521a8054027SBarry 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 25223b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2523a8054027SBarry Smith 2524a8054027SBarry Smith Options Database Keys: 2525a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2526a8054027SBarry Smith 2527a8054027SBarry Smith Notes: 2528a8054027SBarry Smith The default is 1 2529a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2530a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2531a8054027SBarry Smith 2532a8054027SBarry Smith Level: intermediate 2533a8054027SBarry Smith 2534a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2535a8054027SBarry Smith 2536e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2537a8054027SBarry Smith 2538a8054027SBarry Smith @*/ 25397087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2540a8054027SBarry Smith { 2541a8054027SBarry Smith PetscFunctionBegin; 25420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2543e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2544e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2545c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2546a8054027SBarry Smith snes->lagpreconditioner = lag; 2547a8054027SBarry Smith PetscFunctionReturn(0); 2548a8054027SBarry Smith } 2549a8054027SBarry Smith 2550a8054027SBarry Smith #undef __FUNCT__ 2551efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2552efd51863SBarry Smith /*@ 2553efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2554efd51863SBarry Smith 2555efd51863SBarry Smith Logically Collective on SNES 2556efd51863SBarry Smith 2557efd51863SBarry Smith Input Parameters: 2558efd51863SBarry Smith + snes - the SNES context 2559efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2560efd51863SBarry Smith 2561efd51863SBarry Smith Options Database Keys: 2562efd51863SBarry Smith . -snes_grid_sequence <steps> 2563efd51863SBarry Smith 2564efd51863SBarry Smith Level: intermediate 2565efd51863SBarry Smith 2566c0df2a02SJed Brown Notes: 2567c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2568c0df2a02SJed Brown 2569efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2570efd51863SBarry Smith 2571efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2572efd51863SBarry Smith 2573efd51863SBarry Smith @*/ 2574efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2575efd51863SBarry Smith { 2576efd51863SBarry Smith PetscFunctionBegin; 2577efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2578efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2579efd51863SBarry Smith snes->gridsequence = steps; 2580efd51863SBarry Smith PetscFunctionReturn(0); 2581efd51863SBarry Smith } 2582efd51863SBarry Smith 2583efd51863SBarry Smith #undef __FUNCT__ 2584a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2585a8054027SBarry Smith /*@ 2586a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2587a8054027SBarry Smith 25883f9fe445SBarry Smith Not Collective 2589a8054027SBarry Smith 2590a8054027SBarry Smith Input Parameter: 2591a8054027SBarry Smith . snes - the SNES context 2592a8054027SBarry Smith 2593a8054027SBarry Smith Output Parameter: 2594a8054027SBarry 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 25953b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2596a8054027SBarry Smith 2597a8054027SBarry Smith Options Database Keys: 2598a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2599a8054027SBarry Smith 2600a8054027SBarry Smith Notes: 2601a8054027SBarry Smith The default is 1 2602a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2603a8054027SBarry Smith 2604a8054027SBarry Smith Level: intermediate 2605a8054027SBarry Smith 2606a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2607a8054027SBarry Smith 2608a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2609a8054027SBarry Smith 2610a8054027SBarry Smith @*/ 26117087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2612a8054027SBarry Smith { 2613a8054027SBarry Smith PetscFunctionBegin; 26140700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2615a8054027SBarry Smith *lag = snes->lagpreconditioner; 2616a8054027SBarry Smith PetscFunctionReturn(0); 2617a8054027SBarry Smith } 2618a8054027SBarry Smith 2619a8054027SBarry Smith #undef __FUNCT__ 2620e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2621e35cf81dSBarry Smith /*@ 2622e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2623e35cf81dSBarry Smith often the preconditioner is rebuilt. 2624e35cf81dSBarry Smith 26253f9fe445SBarry Smith Logically Collective on SNES 2626e35cf81dSBarry Smith 2627e35cf81dSBarry Smith Input Parameters: 2628e35cf81dSBarry Smith + snes - the SNES context 2629e35cf81dSBarry 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 2630fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2631e35cf81dSBarry Smith 2632e35cf81dSBarry Smith Options Database Keys: 2633e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2634e35cf81dSBarry Smith 2635e35cf81dSBarry Smith Notes: 2636e35cf81dSBarry Smith The default is 1 2637e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2638fe3ffe1eSBarry 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 2639fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2640e35cf81dSBarry Smith 2641e35cf81dSBarry Smith Level: intermediate 2642e35cf81dSBarry Smith 2643e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2644e35cf81dSBarry Smith 2645e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2646e35cf81dSBarry Smith 2647e35cf81dSBarry Smith @*/ 26487087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2649e35cf81dSBarry Smith { 2650e35cf81dSBarry Smith PetscFunctionBegin; 26510700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2652e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2653e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2654c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2655e35cf81dSBarry Smith snes->lagjacobian = lag; 2656e35cf81dSBarry Smith PetscFunctionReturn(0); 2657e35cf81dSBarry Smith } 2658e35cf81dSBarry Smith 2659e35cf81dSBarry Smith #undef __FUNCT__ 2660e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2661e35cf81dSBarry Smith /*@ 2662e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2663e35cf81dSBarry Smith 26643f9fe445SBarry Smith Not Collective 2665e35cf81dSBarry Smith 2666e35cf81dSBarry Smith Input Parameter: 2667e35cf81dSBarry Smith . snes - the SNES context 2668e35cf81dSBarry Smith 2669e35cf81dSBarry Smith Output Parameter: 2670e35cf81dSBarry 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 2671e35cf81dSBarry Smith the Jacobian is built etc. 2672e35cf81dSBarry Smith 2673e35cf81dSBarry Smith Options Database Keys: 2674e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2675e35cf81dSBarry Smith 2676e35cf81dSBarry Smith Notes: 2677e35cf81dSBarry Smith The default is 1 2678e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2679e35cf81dSBarry Smith 2680e35cf81dSBarry Smith Level: intermediate 2681e35cf81dSBarry Smith 2682e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2683e35cf81dSBarry Smith 2684e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2685e35cf81dSBarry Smith 2686e35cf81dSBarry Smith @*/ 26877087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2688e35cf81dSBarry Smith { 2689e35cf81dSBarry Smith PetscFunctionBegin; 26900700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2691e35cf81dSBarry Smith *lag = snes->lagjacobian; 2692e35cf81dSBarry Smith PetscFunctionReturn(0); 2693e35cf81dSBarry Smith } 2694e35cf81dSBarry Smith 2695e35cf81dSBarry Smith #undef __FUNCT__ 26964a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 26979b94acceSBarry Smith /*@ 2698d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 26999b94acceSBarry Smith 27003f9fe445SBarry Smith Logically Collective on SNES 2701c7afd0dbSLois Curfman McInnes 27029b94acceSBarry Smith Input Parameters: 2703c7afd0dbSLois Curfman McInnes + snes - the SNES context 270470441072SBarry Smith . abstol - absolute convergence tolerance 270533174efeSLois Curfman McInnes . rtol - relative convergence tolerance 270633174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 270733174efeSLois Curfman McInnes of the change in the solution between steps 270833174efeSLois Curfman McInnes . maxit - maximum number of iterations 2709c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2710fee21e36SBarry Smith 271133174efeSLois Curfman McInnes Options Database Keys: 271270441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2713c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2714c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2715c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2716c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 27179b94acceSBarry Smith 2718d7a720efSLois Curfman McInnes Notes: 27199b94acceSBarry Smith The default maximum number of iterations is 50. 27209b94acceSBarry Smith The default maximum number of function evaluations is 1000. 27219b94acceSBarry Smith 272236851e7fSLois Curfman McInnes Level: intermediate 272336851e7fSLois Curfman McInnes 272433174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 27259b94acceSBarry Smith 27262492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 27279b94acceSBarry Smith @*/ 27287087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 27299b94acceSBarry Smith { 27303a40ed3dSBarry Smith PetscFunctionBegin; 27310700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2732c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2733c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2734c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2735c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2736c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2737c5eb9154SBarry Smith 2738ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2739ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2740ab54825eSJed Brown snes->abstol = abstol; 2741ab54825eSJed Brown } 2742ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2743ab54825eSJed 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); 2744ab54825eSJed Brown snes->rtol = rtol; 2745ab54825eSJed Brown } 2746ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2747ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2748c60f73f4SPeter Brune snes->stol = stol; 2749ab54825eSJed Brown } 2750ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2751ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2752ab54825eSJed Brown snes->max_its = maxit; 2753ab54825eSJed Brown } 2754ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2755ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2756ab54825eSJed Brown snes->max_funcs = maxf; 2757ab54825eSJed Brown } 275888976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 27593a40ed3dSBarry Smith PetscFunctionReturn(0); 27609b94acceSBarry Smith } 27619b94acceSBarry Smith 27624a2ae208SSatish Balay #undef __FUNCT__ 27634a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 27649b94acceSBarry Smith /*@ 276533174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 276633174efeSLois Curfman McInnes 2767c7afd0dbSLois Curfman McInnes Not Collective 2768c7afd0dbSLois Curfman McInnes 276933174efeSLois Curfman McInnes Input Parameters: 2770c7afd0dbSLois Curfman McInnes + snes - the SNES context 277185385478SLisandro Dalcin . atol - absolute convergence tolerance 277233174efeSLois Curfman McInnes . rtol - relative convergence tolerance 277333174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 277433174efeSLois Curfman McInnes of the change in the solution between steps 277533174efeSLois Curfman McInnes . maxit - maximum number of iterations 2776c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2777fee21e36SBarry Smith 277833174efeSLois Curfman McInnes Notes: 277933174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 278033174efeSLois Curfman McInnes 278136851e7fSLois Curfman McInnes Level: intermediate 278236851e7fSLois Curfman McInnes 278333174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 278433174efeSLois Curfman McInnes 278533174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 278633174efeSLois Curfman McInnes @*/ 27877087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 278833174efeSLois Curfman McInnes { 27893a40ed3dSBarry Smith PetscFunctionBegin; 27900700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 279185385478SLisandro Dalcin if (atol) *atol = snes->abstol; 279233174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 2793c60f73f4SPeter Brune if (stol) *stol = snes->stol; 279433174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 279533174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 27963a40ed3dSBarry Smith PetscFunctionReturn(0); 279733174efeSLois Curfman McInnes } 279833174efeSLois Curfman McInnes 27994a2ae208SSatish Balay #undef __FUNCT__ 28004a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 280133174efeSLois Curfman McInnes /*@ 28029b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 28039b94acceSBarry Smith 28043f9fe445SBarry Smith Logically Collective on SNES 2805fee21e36SBarry Smith 2806c7afd0dbSLois Curfman McInnes Input Parameters: 2807c7afd0dbSLois Curfman McInnes + snes - the SNES context 2808c7afd0dbSLois Curfman McInnes - tol - tolerance 2809c7afd0dbSLois Curfman McInnes 28109b94acceSBarry Smith Options Database Key: 2811c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 28129b94acceSBarry Smith 281336851e7fSLois Curfman McInnes Level: intermediate 281436851e7fSLois Curfman McInnes 28159b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 28169b94acceSBarry Smith 28172492ecdbSBarry Smith .seealso: SNESSetTolerances() 28189b94acceSBarry Smith @*/ 28197087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 28209b94acceSBarry Smith { 28213a40ed3dSBarry Smith PetscFunctionBegin; 28220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2823c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 28249b94acceSBarry Smith snes->deltatol = tol; 28253a40ed3dSBarry Smith PetscFunctionReturn(0); 28269b94acceSBarry Smith } 28279b94acceSBarry Smith 2828df9fa365SBarry Smith /* 2829df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2830df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2831df9fa365SBarry Smith macros instead of functions 2832df9fa365SBarry Smith */ 28334a2ae208SSatish Balay #undef __FUNCT__ 2834a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 28357087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2836ce1608b8SBarry Smith { 2837dfbe8321SBarry Smith PetscErrorCode ierr; 2838ce1608b8SBarry Smith 2839ce1608b8SBarry Smith PetscFunctionBegin; 28400700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2841a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2842ce1608b8SBarry Smith PetscFunctionReturn(0); 2843ce1608b8SBarry Smith } 2844ce1608b8SBarry Smith 28454a2ae208SSatish Balay #undef __FUNCT__ 2846a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 28477087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2848df9fa365SBarry Smith { 2849dfbe8321SBarry Smith PetscErrorCode ierr; 2850df9fa365SBarry Smith 2851df9fa365SBarry Smith PetscFunctionBegin; 2852a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2853df9fa365SBarry Smith PetscFunctionReturn(0); 2854df9fa365SBarry Smith } 2855df9fa365SBarry Smith 28564a2ae208SSatish Balay #undef __FUNCT__ 2857a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 28586bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2859df9fa365SBarry Smith { 2860dfbe8321SBarry Smith PetscErrorCode ierr; 2861df9fa365SBarry Smith 2862df9fa365SBarry Smith PetscFunctionBegin; 2863a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2864df9fa365SBarry Smith PetscFunctionReturn(0); 2865df9fa365SBarry Smith } 2866df9fa365SBarry Smith 28677087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2868b271bb04SBarry Smith #undef __FUNCT__ 2869b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 28707087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2871b271bb04SBarry Smith { 2872b271bb04SBarry Smith PetscDrawLG lg; 2873b271bb04SBarry Smith PetscErrorCode ierr; 2874b271bb04SBarry Smith PetscReal x,y,per; 2875b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2876b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2877b271bb04SBarry Smith PetscDraw draw; 2878b271bb04SBarry Smith PetscFunctionBegin; 2879b271bb04SBarry Smith if (!monctx) { 2880b271bb04SBarry Smith MPI_Comm comm; 2881b271bb04SBarry Smith 2882b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2883b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2884b271bb04SBarry Smith } 2885b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2886b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2887b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2888b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2889b271bb04SBarry Smith x = (PetscReal) n; 2890b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2891b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2892b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2893b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2894b271bb04SBarry Smith } 2895b271bb04SBarry Smith 2896b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2897b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2898b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2899b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2900b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2901b271bb04SBarry Smith x = (PetscReal) n; 2902b271bb04SBarry Smith y = 100.0*per; 2903b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2904b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2905b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2906b271bb04SBarry Smith } 2907b271bb04SBarry Smith 2908b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2909b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2910b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2911b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2912b271bb04SBarry Smith x = (PetscReal) n; 2913b271bb04SBarry Smith y = (prev - rnorm)/prev; 2914b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2915b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2916b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2917b271bb04SBarry Smith } 2918b271bb04SBarry Smith 2919b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2920b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2921b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2922b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2923b271bb04SBarry Smith x = (PetscReal) n; 2924b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2925b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2926b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2927b271bb04SBarry Smith } 2928b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2929b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2930b271bb04SBarry Smith } 2931b271bb04SBarry Smith prev = rnorm; 2932b271bb04SBarry Smith PetscFunctionReturn(0); 2933b271bb04SBarry Smith } 2934b271bb04SBarry Smith 2935b271bb04SBarry Smith #undef __FUNCT__ 2936b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 29377087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2938b271bb04SBarry Smith { 2939b271bb04SBarry Smith PetscErrorCode ierr; 2940b271bb04SBarry Smith 2941b271bb04SBarry Smith PetscFunctionBegin; 2942b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2943b271bb04SBarry Smith PetscFunctionReturn(0); 2944b271bb04SBarry Smith } 2945b271bb04SBarry Smith 2946b271bb04SBarry Smith #undef __FUNCT__ 2947b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 29486bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2949b271bb04SBarry Smith { 2950b271bb04SBarry Smith PetscErrorCode ierr; 2951b271bb04SBarry Smith 2952b271bb04SBarry Smith PetscFunctionBegin; 2953b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2954b271bb04SBarry Smith PetscFunctionReturn(0); 2955b271bb04SBarry Smith } 2956b271bb04SBarry Smith 29577a03ce2fSLisandro Dalcin #undef __FUNCT__ 29587a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 2959228d79bcSJed Brown /*@ 2960228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 2961228d79bcSJed Brown 2962228d79bcSJed Brown Collective on SNES 2963228d79bcSJed Brown 2964228d79bcSJed Brown Input Parameters: 2965228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 2966228d79bcSJed Brown . iter - iteration number 2967228d79bcSJed Brown - rnorm - relative norm of the residual 2968228d79bcSJed Brown 2969228d79bcSJed Brown Notes: 2970228d79bcSJed Brown This routine is called by the SNES implementations. 2971228d79bcSJed Brown It does not typically need to be called by the user. 2972228d79bcSJed Brown 2973228d79bcSJed Brown Level: developer 2974228d79bcSJed Brown 2975228d79bcSJed Brown .seealso: SNESMonitorSet() 2976228d79bcSJed Brown @*/ 29777a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 29787a03ce2fSLisandro Dalcin { 29797a03ce2fSLisandro Dalcin PetscErrorCode ierr; 29807a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 29817a03ce2fSLisandro Dalcin 29827a03ce2fSLisandro Dalcin PetscFunctionBegin; 29837a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 29847a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 29857a03ce2fSLisandro Dalcin } 29867a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 29877a03ce2fSLisandro Dalcin } 29887a03ce2fSLisandro Dalcin 29899b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 29909b94acceSBarry Smith 29914a2ae208SSatish Balay #undef __FUNCT__ 2992a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 29939b94acceSBarry Smith /*@C 2994a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 29959b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 29969b94acceSBarry Smith progress. 29979b94acceSBarry Smith 29983f9fe445SBarry Smith Logically Collective on SNES 2999fee21e36SBarry Smith 3000c7afd0dbSLois Curfman McInnes Input Parameters: 3001c7afd0dbSLois Curfman McInnes + snes - the SNES context 3002c7afd0dbSLois Curfman McInnes . func - monitoring routine 3003b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 3004e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 3005b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 3006b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 30079b94acceSBarry Smith 3008c7afd0dbSLois Curfman McInnes Calling sequence of func: 3009a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 3010c7afd0dbSLois Curfman McInnes 3011c7afd0dbSLois Curfman McInnes + snes - the SNES context 3012c7afd0dbSLois Curfman McInnes . its - iteration number 3013c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 301440a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 30159b94acceSBarry Smith 30169665c990SLois Curfman McInnes Options Database Keys: 3017a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 3018a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 3019a6570f20SBarry Smith uses SNESMonitorLGCreate() 3020cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 3021c7afd0dbSLois Curfman McInnes been hardwired into a code by 3022a6570f20SBarry Smith calls to SNESMonitorSet(), but 3023c7afd0dbSLois Curfman McInnes does not cancel those set via 3024c7afd0dbSLois Curfman McInnes the options database. 30259665c990SLois Curfman McInnes 3026639f9d9dSBarry Smith Notes: 30276bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 3028a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 30296bc08f3fSLois Curfman McInnes order in which they were set. 3030639f9d9dSBarry Smith 3031025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 3032025f1a04SBarry Smith 303336851e7fSLois Curfman McInnes Level: intermediate 303436851e7fSLois Curfman McInnes 30359b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 30369b94acceSBarry Smith 3037a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 30389b94acceSBarry Smith @*/ 3039c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 30409b94acceSBarry Smith { 3041b90d0a6eSBarry Smith PetscInt i; 3042649052a6SBarry Smith PetscErrorCode ierr; 3043b90d0a6eSBarry Smith 30443a40ed3dSBarry Smith PetscFunctionBegin; 30450700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 304617186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 3047b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 3048649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 3049649052a6SBarry Smith if (monitordestroy) { 3050c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 3051649052a6SBarry Smith } 3052b90d0a6eSBarry Smith PetscFunctionReturn(0); 3053b90d0a6eSBarry Smith } 3054b90d0a6eSBarry Smith } 3055b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 3056b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 3057639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 30583a40ed3dSBarry Smith PetscFunctionReturn(0); 30599b94acceSBarry Smith } 30609b94acceSBarry Smith 30614a2ae208SSatish Balay #undef __FUNCT__ 3062a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 30635cd90555SBarry Smith /*@C 3064a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 30655cd90555SBarry Smith 30663f9fe445SBarry Smith Logically Collective on SNES 3067c7afd0dbSLois Curfman McInnes 30685cd90555SBarry Smith Input Parameters: 30695cd90555SBarry Smith . snes - the SNES context 30705cd90555SBarry Smith 30711a480d89SAdministrator Options Database Key: 3072a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 3073a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 3074c7afd0dbSLois Curfman McInnes set via the options database 30755cd90555SBarry Smith 30765cd90555SBarry Smith Notes: 30775cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 30785cd90555SBarry Smith 307936851e7fSLois Curfman McInnes Level: intermediate 308036851e7fSLois Curfman McInnes 30815cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 30825cd90555SBarry Smith 3083a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 30845cd90555SBarry Smith @*/ 30857087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 30865cd90555SBarry Smith { 3087d952e501SBarry Smith PetscErrorCode ierr; 3088d952e501SBarry Smith PetscInt i; 3089d952e501SBarry Smith 30905cd90555SBarry Smith PetscFunctionBegin; 30910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3092d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 3093d952e501SBarry Smith if (snes->monitordestroy[i]) { 30943c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 3095d952e501SBarry Smith } 3096d952e501SBarry Smith } 30975cd90555SBarry Smith snes->numbermonitors = 0; 30985cd90555SBarry Smith PetscFunctionReturn(0); 30995cd90555SBarry Smith } 31005cd90555SBarry Smith 31014a2ae208SSatish Balay #undef __FUNCT__ 31024a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 31039b94acceSBarry Smith /*@C 31049b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 31059b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 31069b94acceSBarry Smith 31073f9fe445SBarry Smith Logically Collective on SNES 3108fee21e36SBarry Smith 3109c7afd0dbSLois Curfman McInnes Input Parameters: 3110c7afd0dbSLois Curfman McInnes + snes - the SNES context 3111c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 31127f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 31137f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 31149b94acceSBarry Smith 3115c7afd0dbSLois Curfman McInnes Calling sequence of func: 311606ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 3117c7afd0dbSLois Curfman McInnes 3118c7afd0dbSLois Curfman McInnes + snes - the SNES context 311906ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 3120c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 3121184914b5SBarry Smith . reason - reason for convergence/divergence 3122c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 31234b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 31244b27c08aSLois Curfman McInnes - f - 2-norm of function 31259b94acceSBarry Smith 312636851e7fSLois Curfman McInnes Level: advanced 312736851e7fSLois Curfman McInnes 31289b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 31299b94acceSBarry Smith 313085385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 31319b94acceSBarry Smith @*/ 31327087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 31339b94acceSBarry Smith { 31347f7931b9SBarry Smith PetscErrorCode ierr; 31357f7931b9SBarry Smith 31363a40ed3dSBarry Smith PetscFunctionBegin; 31370700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 313885385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 31397f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 31407f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 31417f7931b9SBarry Smith } 314285385478SLisandro Dalcin snes->ops->converged = func; 31437f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 314485385478SLisandro Dalcin snes->cnvP = cctx; 31453a40ed3dSBarry Smith PetscFunctionReturn(0); 31469b94acceSBarry Smith } 31479b94acceSBarry Smith 31484a2ae208SSatish Balay #undef __FUNCT__ 31494a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 315052baeb72SSatish Balay /*@ 3151184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 3152184914b5SBarry Smith 3153184914b5SBarry Smith Not Collective 3154184914b5SBarry Smith 3155184914b5SBarry Smith Input Parameter: 3156184914b5SBarry Smith . snes - the SNES context 3157184914b5SBarry Smith 3158184914b5SBarry Smith Output Parameter: 31594d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 3160184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 3161184914b5SBarry Smith 3162184914b5SBarry Smith Level: intermediate 3163184914b5SBarry Smith 3164184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 3165184914b5SBarry Smith 3166184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 3167184914b5SBarry Smith 316885385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 3169184914b5SBarry Smith @*/ 31707087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 3171184914b5SBarry Smith { 3172184914b5SBarry Smith PetscFunctionBegin; 31730700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31744482741eSBarry Smith PetscValidPointer(reason,2); 3175184914b5SBarry Smith *reason = snes->reason; 3176184914b5SBarry Smith PetscFunctionReturn(0); 3177184914b5SBarry Smith } 3178184914b5SBarry Smith 31794a2ae208SSatish Balay #undef __FUNCT__ 31804a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 3181c9005455SLois Curfman McInnes /*@ 3182c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 3183c9005455SLois Curfman McInnes 31843f9fe445SBarry Smith Logically Collective on SNES 3185fee21e36SBarry Smith 3186c7afd0dbSLois Curfman McInnes Input Parameters: 3187c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 31888c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 3189cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 3190758f92a0SBarry Smith . na - size of a and its 319164731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 3192758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 3193c7afd0dbSLois Curfman McInnes 3194308dcc3eSBarry Smith Notes: 3195308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 3196308dcc3eSBarry Smith default array of length 10000 is allocated. 3197308dcc3eSBarry Smith 3198c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 3199c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 3200c9005455SLois Curfman McInnes during the section of code that is being timed. 3201c9005455SLois Curfman McInnes 320236851e7fSLois Curfman McInnes Level: intermediate 320336851e7fSLois Curfman McInnes 3204c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 3205758f92a0SBarry Smith 320608405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 3207758f92a0SBarry Smith 3208c9005455SLois Curfman McInnes @*/ 32097087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 3210c9005455SLois Curfman McInnes { 3211308dcc3eSBarry Smith PetscErrorCode ierr; 3212308dcc3eSBarry Smith 32133a40ed3dSBarry Smith PetscFunctionBegin; 32140700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 32154482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 3216a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 3217308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 3218308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 3219308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 3220308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 3221308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 3222308dcc3eSBarry Smith } 3223c9005455SLois Curfman McInnes snes->conv_hist = a; 3224758f92a0SBarry Smith snes->conv_hist_its = its; 3225758f92a0SBarry Smith snes->conv_hist_max = na; 3226a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 3227758f92a0SBarry Smith snes->conv_hist_reset = reset; 3228758f92a0SBarry Smith PetscFunctionReturn(0); 3229758f92a0SBarry Smith } 3230758f92a0SBarry Smith 3231308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3232c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 3233c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 3234308dcc3eSBarry Smith EXTERN_C_BEGIN 3235308dcc3eSBarry Smith #undef __FUNCT__ 3236308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 3237308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3238308dcc3eSBarry Smith { 3239308dcc3eSBarry Smith mxArray *mat; 3240308dcc3eSBarry Smith PetscInt i; 3241308dcc3eSBarry Smith PetscReal *ar; 3242308dcc3eSBarry Smith 3243308dcc3eSBarry Smith PetscFunctionBegin; 3244308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3245308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3246308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 3247308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 3248308dcc3eSBarry Smith } 3249308dcc3eSBarry Smith PetscFunctionReturn(mat); 3250308dcc3eSBarry Smith } 3251308dcc3eSBarry Smith EXTERN_C_END 3252308dcc3eSBarry Smith #endif 3253308dcc3eSBarry Smith 3254308dcc3eSBarry Smith 32554a2ae208SSatish Balay #undef __FUNCT__ 32564a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 32570c4c9dddSBarry Smith /*@C 3258758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3259758f92a0SBarry Smith 32603f9fe445SBarry Smith Not Collective 3261758f92a0SBarry Smith 3262758f92a0SBarry Smith Input Parameter: 3263758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3264758f92a0SBarry Smith 3265758f92a0SBarry Smith Output Parameters: 3266758f92a0SBarry Smith . a - array to hold history 3267758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3268758f92a0SBarry Smith negative if not converged) for each solve. 3269758f92a0SBarry Smith - na - size of a and its 3270758f92a0SBarry Smith 3271758f92a0SBarry Smith Notes: 3272758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3273758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3274758f92a0SBarry Smith 3275758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3276758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3277758f92a0SBarry Smith during the section of code that is being timed. 3278758f92a0SBarry Smith 3279758f92a0SBarry Smith Level: intermediate 3280758f92a0SBarry Smith 3281758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3282758f92a0SBarry Smith 3283758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3284758f92a0SBarry Smith 3285758f92a0SBarry Smith @*/ 32867087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3287758f92a0SBarry Smith { 3288758f92a0SBarry Smith PetscFunctionBegin; 32890700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3290758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3291758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3292758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 32933a40ed3dSBarry Smith PetscFunctionReturn(0); 3294c9005455SLois Curfman McInnes } 3295c9005455SLois Curfman McInnes 3296e74ef692SMatthew Knepley #undef __FUNCT__ 3297e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 3298ac226902SBarry Smith /*@C 329976b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3300eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 33017e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 330276b2cf59SMatthew Knepley 33033f9fe445SBarry Smith Logically Collective on SNES 330476b2cf59SMatthew Knepley 330576b2cf59SMatthew Knepley Input Parameters: 330676b2cf59SMatthew Knepley . snes - The nonlinear solver context 330776b2cf59SMatthew Knepley . func - The function 330876b2cf59SMatthew Knepley 330976b2cf59SMatthew Knepley Calling sequence of func: 3310b5d30489SBarry Smith . func (SNES snes, PetscInt step); 331176b2cf59SMatthew Knepley 331276b2cf59SMatthew Knepley . step - The current step of the iteration 331376b2cf59SMatthew Knepley 3314fe97e370SBarry Smith Level: advanced 3315fe97e370SBarry Smith 3316fe97e370SBarry 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() 3317fe97e370SBarry Smith This is not used by most users. 331876b2cf59SMatthew Knepley 331976b2cf59SMatthew Knepley .keywords: SNES, update 3320b5d30489SBarry Smith 332185385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 332276b2cf59SMatthew Knepley @*/ 33237087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 332476b2cf59SMatthew Knepley { 332576b2cf59SMatthew Knepley PetscFunctionBegin; 33260700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3327e7788613SBarry Smith snes->ops->update = func; 332876b2cf59SMatthew Knepley PetscFunctionReturn(0); 332976b2cf59SMatthew Knepley } 333076b2cf59SMatthew Knepley 3331e74ef692SMatthew Knepley #undef __FUNCT__ 3332e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 333376b2cf59SMatthew Knepley /*@ 333476b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 333576b2cf59SMatthew Knepley 333676b2cf59SMatthew Knepley Not collective 333776b2cf59SMatthew Knepley 333876b2cf59SMatthew Knepley Input Parameters: 333976b2cf59SMatthew Knepley . snes - The nonlinear solver context 334076b2cf59SMatthew Knepley . step - The current step of the iteration 334176b2cf59SMatthew Knepley 3342205452f4SMatthew Knepley Level: intermediate 3343205452f4SMatthew Knepley 334476b2cf59SMatthew Knepley .keywords: SNES, update 3345a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 334676b2cf59SMatthew Knepley @*/ 33477087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 334876b2cf59SMatthew Knepley { 334976b2cf59SMatthew Knepley PetscFunctionBegin; 335076b2cf59SMatthew Knepley PetscFunctionReturn(0); 335176b2cf59SMatthew Knepley } 335276b2cf59SMatthew Knepley 33534a2ae208SSatish Balay #undef __FUNCT__ 33544a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 33559b94acceSBarry Smith /* 33569b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 33579b94acceSBarry Smith positive parameter delta. 33589b94acceSBarry Smith 33599b94acceSBarry Smith Input Parameters: 3360c7afd0dbSLois Curfman McInnes + snes - the SNES context 33619b94acceSBarry Smith . y - approximate solution of linear system 33629b94acceSBarry Smith . fnorm - 2-norm of current function 3363c7afd0dbSLois Curfman McInnes - delta - trust region size 33649b94acceSBarry Smith 33659b94acceSBarry Smith Output Parameters: 3366c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 33679b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 33689b94acceSBarry Smith region, and exceeds zero otherwise. 3369c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 33709b94acceSBarry Smith 33719b94acceSBarry Smith Note: 33724b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 33739b94acceSBarry Smith is set to be the maximum allowable step size. 33749b94acceSBarry Smith 33759b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 33769b94acceSBarry Smith */ 3377dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 33789b94acceSBarry Smith { 3379064f8208SBarry Smith PetscReal nrm; 3380ea709b57SSatish Balay PetscScalar cnorm; 3381dfbe8321SBarry Smith PetscErrorCode ierr; 33823a40ed3dSBarry Smith 33833a40ed3dSBarry Smith PetscFunctionBegin; 33840700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 33850700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3386c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3387184914b5SBarry Smith 3388064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3389064f8208SBarry Smith if (nrm > *delta) { 3390064f8208SBarry Smith nrm = *delta/nrm; 3391064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3392064f8208SBarry Smith cnorm = nrm; 33932dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 33949b94acceSBarry Smith *ynorm = *delta; 33959b94acceSBarry Smith } else { 33969b94acceSBarry Smith *gpnorm = 0.0; 3397064f8208SBarry Smith *ynorm = nrm; 33989b94acceSBarry Smith } 33993a40ed3dSBarry Smith PetscFunctionReturn(0); 34009b94acceSBarry Smith } 34019b94acceSBarry Smith 34024a2ae208SSatish Balay #undef __FUNCT__ 34034a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 34046ce558aeSBarry Smith /*@C 3405f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3406f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 34079b94acceSBarry Smith 3408c7afd0dbSLois Curfman McInnes Collective on SNES 3409c7afd0dbSLois Curfman McInnes 3410b2002411SLois Curfman McInnes Input Parameters: 3411c7afd0dbSLois Curfman McInnes + snes - the SNES context 34123cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 341385385478SLisandro Dalcin - x - the solution vector. 34149b94acceSBarry Smith 3415b2002411SLois Curfman McInnes Notes: 34168ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 34178ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 34188ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 34198ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 34208ddd3da0SLois Curfman McInnes 342136851e7fSLois Curfman McInnes Level: beginner 342236851e7fSLois Curfman McInnes 34239b94acceSBarry Smith .keywords: SNES, nonlinear, solve 34249b94acceSBarry Smith 3425c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 34269b94acceSBarry Smith @*/ 34277087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 34289b94acceSBarry Smith { 3429dfbe8321SBarry Smith PetscErrorCode ierr; 3430ace3abfcSBarry Smith PetscBool flg; 3431eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 3432eabae89aSBarry Smith PetscViewer viewer; 3433efd51863SBarry Smith PetscInt grid; 3434a69afd8bSBarry Smith Vec xcreated = PETSC_NULL; 3435caa4e7f2SJed Brown DM dm; 3436052efed2SBarry Smith 34373a40ed3dSBarry Smith PetscFunctionBegin; 34380700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3439a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3440a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 34410700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 344285385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 344385385478SLisandro Dalcin 3444caa4e7f2SJed Brown if (!x) { 3445caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3446caa4e7f2SJed Brown ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 3447a69afd8bSBarry Smith x = xcreated; 3448a69afd8bSBarry Smith } 3449a69afd8bSBarry Smith 3450a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3451efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3452efd51863SBarry Smith 345385385478SLisandro Dalcin /* set solution vector */ 3454efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 34556bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 345685385478SLisandro Dalcin snes->vec_sol = x; 3457caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3458caa4e7f2SJed Brown 3459caa4e7f2SJed Brown /* set affine vector if provided */ 346085385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 34616bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 346285385478SLisandro Dalcin snes->vec_rhs = b; 346385385478SLisandro Dalcin 346470e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 34653f149594SLisandro Dalcin 34667eee914bSBarry Smith if (!grid) { 34677eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3468d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3469dd568438SSatish Balay } else if (snes->dm) { 3470dd568438SSatish Balay PetscBool ig; 3471dd568438SSatish Balay ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr); 3472dd568438SSatish Balay if (ig) { 34737eee914bSBarry Smith ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr); 34747eee914bSBarry Smith } 3475d25893d9SBarry Smith } 3476dd568438SSatish Balay } 3477d25893d9SBarry Smith 3478abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 347950ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3480d5e45103SBarry Smith 34813f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 34824936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 348385385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 34844936397dSBarry Smith if (snes->domainerror){ 34854936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 34864936397dSBarry Smith snes->domainerror = PETSC_FALSE; 34874936397dSBarry Smith } 348817186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 34893f149594SLisandro Dalcin 349090d69ab7SBarry Smith flg = PETSC_FALSE; 3491acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3492da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 34935968eb51SBarry Smith if (snes->printreason) { 3494a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 34955968eb51SBarry Smith if (snes->reason > 0) { 3496c7e7b494SJed 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); 34975968eb51SBarry Smith } else { 3498c7e7b494SJed 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); 34995968eb51SBarry Smith } 3500a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 35015968eb51SBarry Smith } 35025968eb51SBarry Smith 3503e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3504efd51863SBarry Smith if (grid < snes->gridsequence) { 3505efd51863SBarry Smith DM fine; 3506efd51863SBarry Smith Vec xnew; 3507efd51863SBarry Smith Mat interp; 3508efd51863SBarry Smith 3509efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3510c5c77316SJed Brown if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 3511e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3512efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3513efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3514c833c3b5SJed Brown ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr); 3515efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3516efd51863SBarry Smith x = xnew; 3517efd51863SBarry Smith 3518efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3519efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3520efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3521a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3522efd51863SBarry Smith } 3523efd51863SBarry Smith } 35243f7e2da0SPeter Brune /* monitoring and viewing */ 35253f7e2da0SPeter Brune flg = PETSC_FALSE; 35263f7e2da0SPeter Brune ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 35273f7e2da0SPeter Brune if (flg && !PetscPreLoadingOn) { 35283f7e2da0SPeter Brune ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 35293f7e2da0SPeter Brune ierr = SNESView(snes,viewer);CHKERRQ(ierr); 35303f7e2da0SPeter Brune ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 35313f7e2da0SPeter Brune } 35323f7e2da0SPeter Brune 35333f7e2da0SPeter Brune flg = PETSC_FALSE; 35343f7e2da0SPeter Brune ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 35353f7e2da0SPeter Brune if (flg) { 35363f7e2da0SPeter Brune PetscViewer viewer; 35373f7e2da0SPeter Brune ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 35383f7e2da0SPeter Brune ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 35393f7e2da0SPeter Brune ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 35403f7e2da0SPeter Brune ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 35413f7e2da0SPeter Brune ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 35423f7e2da0SPeter Brune } 35433f7e2da0SPeter Brune 3544a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 35453a40ed3dSBarry Smith PetscFunctionReturn(0); 35469b94acceSBarry Smith } 35479b94acceSBarry Smith 35489b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 35499b94acceSBarry Smith 35504a2ae208SSatish Balay #undef __FUNCT__ 35514a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 355282bf6240SBarry Smith /*@C 35534b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 35549b94acceSBarry Smith 3555fee21e36SBarry Smith Collective on SNES 3556fee21e36SBarry Smith 3557c7afd0dbSLois Curfman McInnes Input Parameters: 3558c7afd0dbSLois Curfman McInnes + snes - the SNES context 3559454a90a3SBarry Smith - type - a known method 3560c7afd0dbSLois Curfman McInnes 3561c7afd0dbSLois Curfman McInnes Options Database Key: 3562454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3563c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3564ae12b187SLois Curfman McInnes 35659b94acceSBarry Smith Notes: 3566e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 35674b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3568c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 35694b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3570c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 35719b94acceSBarry Smith 3572ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3573ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3574ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3575ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3576ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3577ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3578ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3579ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3580ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3581b0a32e0cSBarry Smith appropriate method. 358236851e7fSLois Curfman McInnes 358336851e7fSLois Curfman McInnes Level: intermediate 3584a703fe33SLois Curfman McInnes 3585454a90a3SBarry Smith .keywords: SNES, set, type 3586435da068SBarry Smith 3587435da068SBarry Smith .seealso: SNESType, SNESCreate() 3588435da068SBarry Smith 35899b94acceSBarry Smith @*/ 35907087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 35919b94acceSBarry Smith { 3592dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3593ace3abfcSBarry Smith PetscBool match; 35943a40ed3dSBarry Smith 35953a40ed3dSBarry Smith PetscFunctionBegin; 35960700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35974482741eSBarry Smith PetscValidCharPointer(type,2); 359882bf6240SBarry Smith 3599251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 36000f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 360192ff6ae8SBarry Smith 36024b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3603e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 360475396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 3605b5c23020SJed Brown if (snes->ops->destroy) { 3606b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 3607b5c23020SJed Brown snes->ops->destroy = PETSC_NULL; 3608b5c23020SJed Brown } 360975396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 361075396ef9SLisandro Dalcin snes->ops->setup = 0; 361175396ef9SLisandro Dalcin snes->ops->solve = 0; 361275396ef9SLisandro Dalcin snes->ops->view = 0; 361375396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 361475396ef9SLisandro Dalcin snes->ops->destroy = 0; 361575396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 361675396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3617454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 361803bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 36199fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 36209fb22e1aSBarry Smith if (PetscAMSPublishAll) { 36219fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 36229fb22e1aSBarry Smith } 36239fb22e1aSBarry Smith #endif 36243a40ed3dSBarry Smith PetscFunctionReturn(0); 36259b94acceSBarry Smith } 36269b94acceSBarry Smith 3627a847f771SSatish Balay 36289b94acceSBarry Smith /* --------------------------------------------------------------------- */ 36294a2ae208SSatish Balay #undef __FUNCT__ 36304a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 363152baeb72SSatish Balay /*@ 36329b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3633f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 36349b94acceSBarry Smith 3635fee21e36SBarry Smith Not Collective 3636fee21e36SBarry Smith 363736851e7fSLois Curfman McInnes Level: advanced 363836851e7fSLois Curfman McInnes 36399b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 36409b94acceSBarry Smith 36419b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 36429b94acceSBarry Smith @*/ 36437087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 36449b94acceSBarry Smith { 3645dfbe8321SBarry Smith PetscErrorCode ierr; 364682bf6240SBarry Smith 36473a40ed3dSBarry Smith PetscFunctionBegin; 36481441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 36494c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 36503a40ed3dSBarry Smith PetscFunctionReturn(0); 36519b94acceSBarry Smith } 36529b94acceSBarry Smith 36534a2ae208SSatish Balay #undef __FUNCT__ 36544a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 36559b94acceSBarry Smith /*@C 36569a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 36579b94acceSBarry Smith 3658c7afd0dbSLois Curfman McInnes Not Collective 3659c7afd0dbSLois Curfman McInnes 36609b94acceSBarry Smith Input Parameter: 36614b0e389bSBarry Smith . snes - nonlinear solver context 36629b94acceSBarry Smith 36639b94acceSBarry Smith Output Parameter: 36643a7fca6bSBarry Smith . type - SNES method (a character string) 36659b94acceSBarry Smith 366636851e7fSLois Curfman McInnes Level: intermediate 366736851e7fSLois Curfman McInnes 3668454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 36699b94acceSBarry Smith @*/ 36707087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 36719b94acceSBarry Smith { 36723a40ed3dSBarry Smith PetscFunctionBegin; 36730700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36744482741eSBarry Smith PetscValidPointer(type,2); 36757adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 36763a40ed3dSBarry Smith PetscFunctionReturn(0); 36779b94acceSBarry Smith } 36789b94acceSBarry Smith 36794a2ae208SSatish Balay #undef __FUNCT__ 36804a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 368152baeb72SSatish Balay /*@ 36829b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3683c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 36849b94acceSBarry Smith 3685c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3686c7afd0dbSLois Curfman McInnes 36879b94acceSBarry Smith Input Parameter: 36889b94acceSBarry Smith . snes - the SNES context 36899b94acceSBarry Smith 36909b94acceSBarry Smith Output Parameter: 36919b94acceSBarry Smith . x - the solution 36929b94acceSBarry Smith 369370e92668SMatthew Knepley Level: intermediate 369436851e7fSLois Curfman McInnes 36959b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 36969b94acceSBarry Smith 369785385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 36989b94acceSBarry Smith @*/ 36997087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 37009b94acceSBarry Smith { 37013a40ed3dSBarry Smith PetscFunctionBegin; 37020700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37034482741eSBarry Smith PetscValidPointer(x,2); 370485385478SLisandro Dalcin *x = snes->vec_sol; 370570e92668SMatthew Knepley PetscFunctionReturn(0); 370670e92668SMatthew Knepley } 370770e92668SMatthew Knepley 370870e92668SMatthew Knepley #undef __FUNCT__ 37094a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 371052baeb72SSatish Balay /*@ 37119b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 37129b94acceSBarry Smith stored. 37139b94acceSBarry Smith 3714c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3715c7afd0dbSLois Curfman McInnes 37169b94acceSBarry Smith Input Parameter: 37179b94acceSBarry Smith . snes - the SNES context 37189b94acceSBarry Smith 37199b94acceSBarry Smith Output Parameter: 37209b94acceSBarry Smith . x - the solution update 37219b94acceSBarry Smith 372236851e7fSLois Curfman McInnes Level: advanced 372336851e7fSLois Curfman McInnes 37249b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 37259b94acceSBarry Smith 372685385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 37279b94acceSBarry Smith @*/ 37287087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 37299b94acceSBarry Smith { 37303a40ed3dSBarry Smith PetscFunctionBegin; 37310700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37324482741eSBarry Smith PetscValidPointer(x,2); 373385385478SLisandro Dalcin *x = snes->vec_sol_update; 37343a40ed3dSBarry Smith PetscFunctionReturn(0); 37359b94acceSBarry Smith } 37369b94acceSBarry Smith 37374a2ae208SSatish Balay #undef __FUNCT__ 37384a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 37399b94acceSBarry Smith /*@C 37403638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 37419b94acceSBarry Smith 3742a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 3743c7afd0dbSLois Curfman McInnes 37449b94acceSBarry Smith Input Parameter: 37459b94acceSBarry Smith . snes - the SNES context 37469b94acceSBarry Smith 37479b94acceSBarry Smith Output Parameter: 37487bf4e008SBarry Smith + r - the function (or PETSC_NULL) 374970e92668SMatthew Knepley . func - the function (or PETSC_NULL) 375070e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 37519b94acceSBarry Smith 375236851e7fSLois Curfman McInnes Level: advanced 375336851e7fSLois Curfman McInnes 3754a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 37559b94acceSBarry Smith 37564b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 37579b94acceSBarry Smith @*/ 37587087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 37599b94acceSBarry Smith { 3760a63bb30eSJed Brown PetscErrorCode ierr; 37616cab3a1bSJed Brown DM dm; 3762a63bb30eSJed Brown 37633a40ed3dSBarry Smith PetscFunctionBegin; 37640700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3765a63bb30eSJed Brown if (r) { 3766a63bb30eSJed Brown if (!snes->vec_func) { 3767a63bb30eSJed Brown if (snes->vec_rhs) { 3768a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 3769a63bb30eSJed Brown } else if (snes->vec_sol) { 3770a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 3771a63bb30eSJed Brown } else if (snes->dm) { 3772a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 3773a63bb30eSJed Brown } 3774a63bb30eSJed Brown } 3775a63bb30eSJed Brown *r = snes->vec_func; 3776a63bb30eSJed Brown } 37776cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 37786cab3a1bSJed Brown ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr); 37793a40ed3dSBarry Smith PetscFunctionReturn(0); 37809b94acceSBarry Smith } 37819b94acceSBarry Smith 3782c79ef259SPeter Brune /*@C 3783c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3784c79ef259SPeter Brune 3785c79ef259SPeter Brune Input Parameter: 3786c79ef259SPeter Brune . snes - the SNES context 3787c79ef259SPeter Brune 3788c79ef259SPeter Brune Output Parameter: 3789c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3790c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3791c79ef259SPeter Brune 3792c79ef259SPeter Brune Level: advanced 3793c79ef259SPeter Brune 3794c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3795c79ef259SPeter Brune 3796c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3797c79ef259SPeter Brune @*/ 3798c79ef259SPeter Brune 37994a2ae208SSatish Balay #undef __FUNCT__ 3800646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3801646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3802646217ecSPeter Brune { 38036cab3a1bSJed Brown PetscErrorCode ierr; 38046cab3a1bSJed Brown DM dm; 38056cab3a1bSJed Brown 3806646217ecSPeter Brune PetscFunctionBegin; 3807646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 38086cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 38096cab3a1bSJed Brown ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr); 3810646217ecSPeter Brune PetscFunctionReturn(0); 3811646217ecSPeter Brune } 3812646217ecSPeter Brune 38134a2ae208SSatish Balay #undef __FUNCT__ 38144a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 38153c7409f5SSatish Balay /*@C 38163c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3817d850072dSLois Curfman McInnes SNES options in the database. 38183c7409f5SSatish Balay 38193f9fe445SBarry Smith Logically Collective on SNES 3820fee21e36SBarry Smith 3821c7afd0dbSLois Curfman McInnes Input Parameter: 3822c7afd0dbSLois Curfman McInnes + snes - the SNES context 3823c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3824c7afd0dbSLois Curfman McInnes 3825d850072dSLois Curfman McInnes Notes: 3826a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3827c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3828d850072dSLois Curfman McInnes 382936851e7fSLois Curfman McInnes Level: advanced 383036851e7fSLois Curfman McInnes 38313c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3832a86d99e1SLois Curfman McInnes 3833a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 38343c7409f5SSatish Balay @*/ 38357087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 38363c7409f5SSatish Balay { 3837dfbe8321SBarry Smith PetscErrorCode ierr; 38383c7409f5SSatish Balay 38393a40ed3dSBarry Smith PetscFunctionBegin; 38400700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3841639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 38421cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 384394b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 38443a40ed3dSBarry Smith PetscFunctionReturn(0); 38453c7409f5SSatish Balay } 38463c7409f5SSatish Balay 38474a2ae208SSatish Balay #undef __FUNCT__ 38484a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 38493c7409f5SSatish Balay /*@C 3850f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3851d850072dSLois Curfman McInnes SNES options in the database. 38523c7409f5SSatish Balay 38533f9fe445SBarry Smith Logically Collective on SNES 3854fee21e36SBarry Smith 3855c7afd0dbSLois Curfman McInnes Input Parameters: 3856c7afd0dbSLois Curfman McInnes + snes - the SNES context 3857c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3858c7afd0dbSLois Curfman McInnes 3859d850072dSLois Curfman McInnes Notes: 3860a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3861c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3862d850072dSLois Curfman McInnes 386336851e7fSLois Curfman McInnes Level: advanced 386436851e7fSLois Curfman McInnes 38653c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3866a86d99e1SLois Curfman McInnes 3867a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 38683c7409f5SSatish Balay @*/ 38697087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 38703c7409f5SSatish Balay { 3871dfbe8321SBarry Smith PetscErrorCode ierr; 38723c7409f5SSatish Balay 38733a40ed3dSBarry Smith PetscFunctionBegin; 38740700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3875639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 38761cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 387794b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 38783a40ed3dSBarry Smith PetscFunctionReturn(0); 38793c7409f5SSatish Balay } 38803c7409f5SSatish Balay 38814a2ae208SSatish Balay #undef __FUNCT__ 38824a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 38839ab63eb5SSatish Balay /*@C 38843c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 38853c7409f5SSatish Balay SNES options in the database. 38863c7409f5SSatish Balay 3887c7afd0dbSLois Curfman McInnes Not Collective 3888c7afd0dbSLois Curfman McInnes 38893c7409f5SSatish Balay Input Parameter: 38903c7409f5SSatish Balay . snes - the SNES context 38913c7409f5SSatish Balay 38923c7409f5SSatish Balay Output Parameter: 38933c7409f5SSatish Balay . prefix - pointer to the prefix string used 38943c7409f5SSatish Balay 38954ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 38969ab63eb5SSatish Balay sufficient length to hold the prefix. 38979ab63eb5SSatish Balay 389836851e7fSLois Curfman McInnes Level: advanced 389936851e7fSLois Curfman McInnes 39003c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 3901a86d99e1SLois Curfman McInnes 3902a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 39033c7409f5SSatish Balay @*/ 39047087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 39053c7409f5SSatish Balay { 3906dfbe8321SBarry Smith PetscErrorCode ierr; 39073c7409f5SSatish Balay 39083a40ed3dSBarry Smith PetscFunctionBegin; 39090700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3910639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 39113a40ed3dSBarry Smith PetscFunctionReturn(0); 39123c7409f5SSatish Balay } 39133c7409f5SSatish Balay 3914b2002411SLois Curfman McInnes 39154a2ae208SSatish Balay #undef __FUNCT__ 39164a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 39173cea93caSBarry Smith /*@C 39183cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 39193cea93caSBarry Smith 39207f6c08e0SMatthew Knepley Level: advanced 39213cea93caSBarry Smith @*/ 39227087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3923b2002411SLois Curfman McInnes { 3924e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3925dfbe8321SBarry Smith PetscErrorCode ierr; 3926b2002411SLois Curfman McInnes 3927b2002411SLois Curfman McInnes PetscFunctionBegin; 3928b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3929c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3930b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3931b2002411SLois Curfman McInnes } 3932da9b6338SBarry Smith 3933da9b6338SBarry Smith #undef __FUNCT__ 3934da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 39357087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3936da9b6338SBarry Smith { 3937dfbe8321SBarry Smith PetscErrorCode ierr; 393877431f27SBarry Smith PetscInt N,i,j; 3939da9b6338SBarry Smith Vec u,uh,fh; 3940da9b6338SBarry Smith PetscScalar value; 3941da9b6338SBarry Smith PetscReal norm; 3942da9b6338SBarry Smith 3943da9b6338SBarry Smith PetscFunctionBegin; 3944da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3945da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3946da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3947da9b6338SBarry Smith 3948da9b6338SBarry Smith /* currently only works for sequential */ 3949da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3950da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3951da9b6338SBarry Smith for (i=0; i<N; i++) { 3952da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 395377431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3954da9b6338SBarry Smith for (j=-10; j<11; j++) { 3955ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3956da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 39573ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3958da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 395977431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3960da9b6338SBarry Smith value = -value; 3961da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3962da9b6338SBarry Smith } 3963da9b6338SBarry Smith } 39646bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 39656bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 3966da9b6338SBarry Smith PetscFunctionReturn(0); 3967da9b6338SBarry Smith } 396871f87433Sdalcinl 396971f87433Sdalcinl #undef __FUNCT__ 3970fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 397171f87433Sdalcinl /*@ 3972fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 397371f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 397471f87433Sdalcinl Newton method. 397571f87433Sdalcinl 39763f9fe445SBarry Smith Logically Collective on SNES 397771f87433Sdalcinl 397871f87433Sdalcinl Input Parameters: 397971f87433Sdalcinl + snes - SNES context 398071f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 398171f87433Sdalcinl 398264ba62caSBarry Smith Options Database: 398364ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 398464ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 398564ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 398664ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 398764ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 398864ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 398964ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 399064ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 399164ba62caSBarry Smith 399271f87433Sdalcinl Notes: 399371f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 399471f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 399571f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 399671f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 399771f87433Sdalcinl solver. 399871f87433Sdalcinl 399971f87433Sdalcinl Level: advanced 400071f87433Sdalcinl 400171f87433Sdalcinl Reference: 400271f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 400371f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 400471f87433Sdalcinl 400571f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 400671f87433Sdalcinl 4007fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 400871f87433Sdalcinl @*/ 40097087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 401071f87433Sdalcinl { 401171f87433Sdalcinl PetscFunctionBegin; 40120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4013acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 401471f87433Sdalcinl snes->ksp_ewconv = flag; 401571f87433Sdalcinl PetscFunctionReturn(0); 401671f87433Sdalcinl } 401771f87433Sdalcinl 401871f87433Sdalcinl #undef __FUNCT__ 4019fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 402071f87433Sdalcinl /*@ 4021fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 402271f87433Sdalcinl for computing relative tolerance for linear solvers within an 402371f87433Sdalcinl inexact Newton method. 402471f87433Sdalcinl 402571f87433Sdalcinl Not Collective 402671f87433Sdalcinl 402771f87433Sdalcinl Input Parameter: 402871f87433Sdalcinl . snes - SNES context 402971f87433Sdalcinl 403071f87433Sdalcinl Output Parameter: 403171f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 403271f87433Sdalcinl 403371f87433Sdalcinl Notes: 403471f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 403571f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 403671f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 403771f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 403871f87433Sdalcinl solver. 403971f87433Sdalcinl 404071f87433Sdalcinl Level: advanced 404171f87433Sdalcinl 404271f87433Sdalcinl Reference: 404371f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 404471f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 404571f87433Sdalcinl 404671f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 404771f87433Sdalcinl 4048fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 404971f87433Sdalcinl @*/ 40507087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 405171f87433Sdalcinl { 405271f87433Sdalcinl PetscFunctionBegin; 40530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 405471f87433Sdalcinl PetscValidPointer(flag,2); 405571f87433Sdalcinl *flag = snes->ksp_ewconv; 405671f87433Sdalcinl PetscFunctionReturn(0); 405771f87433Sdalcinl } 405871f87433Sdalcinl 405971f87433Sdalcinl #undef __FUNCT__ 4060fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 406171f87433Sdalcinl /*@ 4062fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 406371f87433Sdalcinl convergence criteria for the linear solvers within an inexact 406471f87433Sdalcinl Newton method. 406571f87433Sdalcinl 40663f9fe445SBarry Smith Logically Collective on SNES 406771f87433Sdalcinl 406871f87433Sdalcinl Input Parameters: 406971f87433Sdalcinl + snes - SNES context 407071f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 407171f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 407271f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 407371f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 407471f87433Sdalcinl (0 <= gamma2 <= 1) 407571f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 407671f87433Sdalcinl . alpha2 - power for safeguard 407771f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 407871f87433Sdalcinl 407971f87433Sdalcinl Note: 408071f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 408171f87433Sdalcinl 408271f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 408371f87433Sdalcinl 408471f87433Sdalcinl Level: advanced 408571f87433Sdalcinl 408671f87433Sdalcinl Reference: 408771f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 408871f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 408971f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 409071f87433Sdalcinl 409171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 409271f87433Sdalcinl 4093fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 409471f87433Sdalcinl @*/ 40957087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 409671f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 409771f87433Sdalcinl { 4098fa9f3622SBarry Smith SNESKSPEW *kctx; 409971f87433Sdalcinl PetscFunctionBegin; 41000700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4101fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4102e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 4103c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 4104c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 4105c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 4106c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 4107c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 4108c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 4109c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 411071f87433Sdalcinl 411171f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 411271f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 411371f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 411471f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 411571f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 411671f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 411771f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 411871f87433Sdalcinl 411971f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 4120e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 412171f87433Sdalcinl } 412271f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 4123e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 412471f87433Sdalcinl } 412571f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 4126e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 412771f87433Sdalcinl } 412871f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 4129e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 413071f87433Sdalcinl } 413171f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 4132e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 413371f87433Sdalcinl } 413471f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 4135e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 413671f87433Sdalcinl } 413771f87433Sdalcinl PetscFunctionReturn(0); 413871f87433Sdalcinl } 413971f87433Sdalcinl 414071f87433Sdalcinl #undef __FUNCT__ 4141fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 414271f87433Sdalcinl /*@ 4143fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 414471f87433Sdalcinl convergence criteria for the linear solvers within an inexact 414571f87433Sdalcinl Newton method. 414671f87433Sdalcinl 414771f87433Sdalcinl Not Collective 414871f87433Sdalcinl 414971f87433Sdalcinl Input Parameters: 415071f87433Sdalcinl snes - SNES context 415171f87433Sdalcinl 415271f87433Sdalcinl Output Parameters: 415371f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 415471f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 415571f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 415671f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 415771f87433Sdalcinl (0 <= gamma2 <= 1) 415871f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 415971f87433Sdalcinl . alpha2 - power for safeguard 416071f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 416171f87433Sdalcinl 416271f87433Sdalcinl Level: advanced 416371f87433Sdalcinl 416471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 416571f87433Sdalcinl 4166fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 416771f87433Sdalcinl @*/ 41687087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 416971f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 417071f87433Sdalcinl { 4171fa9f3622SBarry Smith SNESKSPEW *kctx; 417271f87433Sdalcinl PetscFunctionBegin; 41730700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4174fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4175e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 417671f87433Sdalcinl if(version) *version = kctx->version; 417771f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 417871f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 417971f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 418071f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 418171f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 418271f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 418371f87433Sdalcinl PetscFunctionReturn(0); 418471f87433Sdalcinl } 418571f87433Sdalcinl 418671f87433Sdalcinl #undef __FUNCT__ 4187fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 4188fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 418971f87433Sdalcinl { 419071f87433Sdalcinl PetscErrorCode ierr; 4191fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 419271f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 419371f87433Sdalcinl 419471f87433Sdalcinl PetscFunctionBegin; 4195e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 419671f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 419771f87433Sdalcinl rtol = kctx->rtol_0; 419871f87433Sdalcinl } else { 419971f87433Sdalcinl if (kctx->version == 1) { 420071f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 420171f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 420271f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 420371f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 420471f87433Sdalcinl } else if (kctx->version == 2) { 420571f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 420671f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 420771f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 420871f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 420971f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 421071f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 421171f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 421271f87433Sdalcinl stol = PetscMax(rtol,stol); 421371f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 421471f87433Sdalcinl /* safeguard: avoid oversolving */ 421571f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 421671f87433Sdalcinl stol = PetscMax(rtol,stol); 421771f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 4218e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 421971f87433Sdalcinl } 422071f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 422171f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 422271f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 422371f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 422471f87433Sdalcinl PetscFunctionReturn(0); 422571f87433Sdalcinl } 422671f87433Sdalcinl 422771f87433Sdalcinl #undef __FUNCT__ 4228fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 4229fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 423071f87433Sdalcinl { 423171f87433Sdalcinl PetscErrorCode ierr; 4232fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 423371f87433Sdalcinl PCSide pcside; 423471f87433Sdalcinl Vec lres; 423571f87433Sdalcinl 423671f87433Sdalcinl PetscFunctionBegin; 4237e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 423871f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 423971f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 424071f87433Sdalcinl if (kctx->version == 1) { 4241b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 424271f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 424371f87433Sdalcinl /* KSP residual is true linear residual */ 424471f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 424571f87433Sdalcinl } else { 424671f87433Sdalcinl /* KSP residual is preconditioned residual */ 424771f87433Sdalcinl /* compute true linear residual norm */ 424871f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 424971f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 425071f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 425171f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 42526bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 425371f87433Sdalcinl } 425471f87433Sdalcinl } 425571f87433Sdalcinl PetscFunctionReturn(0); 425671f87433Sdalcinl } 425771f87433Sdalcinl 425871f87433Sdalcinl #undef __FUNCT__ 425971f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 426071f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 426171f87433Sdalcinl { 426271f87433Sdalcinl PetscErrorCode ierr; 426371f87433Sdalcinl 426471f87433Sdalcinl PetscFunctionBegin; 4265fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 426671f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 4267fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 426871f87433Sdalcinl PetscFunctionReturn(0); 426971f87433Sdalcinl } 42706c699258SBarry Smith 42716c699258SBarry Smith #undef __FUNCT__ 42726c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 42736c699258SBarry Smith /*@ 42746c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 42756c699258SBarry Smith 42763f9fe445SBarry Smith Logically Collective on SNES 42776c699258SBarry Smith 42786c699258SBarry Smith Input Parameters: 42796c699258SBarry Smith + snes - the preconditioner context 42806c699258SBarry Smith - dm - the dm 42816c699258SBarry Smith 42826c699258SBarry Smith Level: intermediate 42836c699258SBarry Smith 42846c699258SBarry Smith 42856c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 42866c699258SBarry Smith @*/ 42877087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 42886c699258SBarry Smith { 42896c699258SBarry Smith PetscErrorCode ierr; 4290345fed2cSBarry Smith KSP ksp; 42916cab3a1bSJed Brown SNESDM sdm; 42926c699258SBarry Smith 42936c699258SBarry Smith PetscFunctionBegin; 42940700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4295d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 42966cab3a1bSJed Brown if (snes->dm) { /* Move the SNESDM context over to the new DM unless the new DM already has one */ 42976cab3a1bSJed Brown PetscContainer oldcontainer,container; 42986cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 42996cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr); 43006cab3a1bSJed Brown if (oldcontainer && !container) { 43016cab3a1bSJed Brown ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr); 43026cab3a1bSJed Brown ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr); 43036cab3a1bSJed Brown if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */ 43046cab3a1bSJed Brown sdm->originaldm = dm; 43056cab3a1bSJed Brown } 43066cab3a1bSJed Brown } 43076bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 43086cab3a1bSJed Brown } 43096c699258SBarry Smith snes->dm = dm; 4310345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4311345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4312f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 43132c155ee1SBarry Smith if (snes->pc) { 43142c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 43152c155ee1SBarry Smith } 43166c699258SBarry Smith PetscFunctionReturn(0); 43176c699258SBarry Smith } 43186c699258SBarry Smith 43196c699258SBarry Smith #undef __FUNCT__ 43206c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 43216c699258SBarry Smith /*@ 43226c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 43236c699258SBarry Smith 43243f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 43256c699258SBarry Smith 43266c699258SBarry Smith Input Parameter: 43276c699258SBarry Smith . snes - the preconditioner context 43286c699258SBarry Smith 43296c699258SBarry Smith Output Parameter: 43306c699258SBarry Smith . dm - the dm 43316c699258SBarry Smith 43326c699258SBarry Smith Level: intermediate 43336c699258SBarry Smith 43346c699258SBarry Smith 43356c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 43366c699258SBarry Smith @*/ 43377087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 43386c699258SBarry Smith { 43396cab3a1bSJed Brown PetscErrorCode ierr; 43406cab3a1bSJed Brown 43416c699258SBarry Smith PetscFunctionBegin; 43420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 43436cab3a1bSJed Brown if (!snes->dm) { 43446cab3a1bSJed Brown ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr); 43456cab3a1bSJed Brown } 43466c699258SBarry Smith *dm = snes->dm; 43476c699258SBarry Smith PetscFunctionReturn(0); 43486c699258SBarry Smith } 43490807856dSBarry Smith 435031823bd8SMatthew G Knepley #undef __FUNCT__ 435131823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 435231823bd8SMatthew G Knepley /*@ 4353fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 435431823bd8SMatthew G Knepley 435531823bd8SMatthew G Knepley Collective on SNES 435631823bd8SMatthew G Knepley 435731823bd8SMatthew G Knepley Input Parameters: 435831823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 435931823bd8SMatthew G Knepley - pc - the preconditioner object 436031823bd8SMatthew G Knepley 436131823bd8SMatthew G Knepley Notes: 436231823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 436331823bd8SMatthew G Knepley to configure it using the API). 436431823bd8SMatthew G Knepley 436531823bd8SMatthew G Knepley Level: developer 436631823bd8SMatthew G Knepley 436731823bd8SMatthew G Knepley .keywords: SNES, set, precondition 436831823bd8SMatthew G Knepley .seealso: SNESGetPC() 436931823bd8SMatthew G Knepley @*/ 437031823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 437131823bd8SMatthew G Knepley { 437231823bd8SMatthew G Knepley PetscErrorCode ierr; 437331823bd8SMatthew G Knepley 437431823bd8SMatthew G Knepley PetscFunctionBegin; 437531823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 437631823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 437731823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 437831823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4379bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 438031823bd8SMatthew G Knepley snes->pc = pc; 438131823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 438231823bd8SMatthew G Knepley PetscFunctionReturn(0); 438331823bd8SMatthew G Knepley } 438431823bd8SMatthew G Knepley 438531823bd8SMatthew G Knepley #undef __FUNCT__ 438631823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 438731823bd8SMatthew G Knepley /*@ 4388fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 438931823bd8SMatthew G Knepley 439031823bd8SMatthew G Knepley Not Collective 439131823bd8SMatthew G Knepley 439231823bd8SMatthew G Knepley Input Parameter: 439331823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 439431823bd8SMatthew G Knepley 439531823bd8SMatthew G Knepley Output Parameter: 439631823bd8SMatthew G Knepley . pc - preconditioner context 439731823bd8SMatthew G Knepley 439831823bd8SMatthew G Knepley Level: developer 439931823bd8SMatthew G Knepley 440031823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 440131823bd8SMatthew G Knepley .seealso: SNESSetPC() 440231823bd8SMatthew G Knepley @*/ 440331823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 440431823bd8SMatthew G Knepley { 440531823bd8SMatthew G Knepley PetscErrorCode ierr; 4406a64e098fSPeter Brune const char *optionsprefix; 440731823bd8SMatthew G Knepley 440831823bd8SMatthew G Knepley PetscFunctionBegin; 440931823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 441031823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 441131823bd8SMatthew G Knepley if (!snes->pc) { 441231823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm,&snes->pc);CHKERRQ(ierr); 44134a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr); 441431823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes,snes->pc);CHKERRQ(ierr); 4415a64e098fSPeter Brune ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr); 4416a64e098fSPeter Brune ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr); 4417a64e098fSPeter Brune ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr); 441831823bd8SMatthew G Knepley } 441931823bd8SMatthew G Knepley *pc = snes->pc; 442031823bd8SMatthew G Knepley PetscFunctionReturn(0); 442131823bd8SMatthew G Knepley } 442231823bd8SMatthew G Knepley 44239e764e56SPeter Brune #undef __FUNCT__ 4424f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch" 44259e764e56SPeter Brune /*@ 44268141a3b9SPeter Brune SNESSetSNESLineSearch - Sets the linesearch on the SNES instance. 44279e764e56SPeter Brune 44289e764e56SPeter Brune Collective on SNES 44299e764e56SPeter Brune 44309e764e56SPeter Brune Input Parameters: 44319e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 44329e764e56SPeter Brune - linesearch - the linesearch object 44339e764e56SPeter Brune 44349e764e56SPeter Brune Notes: 4435f1c6b773SPeter Brune Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example, 44369e764e56SPeter Brune to configure it using the API). 44379e764e56SPeter Brune 44389e764e56SPeter Brune Level: developer 44399e764e56SPeter Brune 44409e764e56SPeter Brune .keywords: SNES, set, linesearch 4441f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch() 44429e764e56SPeter Brune @*/ 4443f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch) 44449e764e56SPeter Brune { 44459e764e56SPeter Brune PetscErrorCode ierr; 44469e764e56SPeter Brune 44479e764e56SPeter Brune PetscFunctionBegin; 44489e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4449f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 44509e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 44519e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 4452f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 44539e764e56SPeter Brune snes->linesearch = linesearch; 44549e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 44559e764e56SPeter Brune PetscFunctionReturn(0); 44569e764e56SPeter Brune } 44579e764e56SPeter Brune 44589e764e56SPeter Brune #undef __FUNCT__ 4459f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch" 4460ea5d4fccSPeter Brune /*@C 44618141a3b9SPeter Brune SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 44628141a3b9SPeter Brune or creates a default line search instance associated with the SNES and returns it. 44639e764e56SPeter Brune 44649e764e56SPeter Brune Not Collective 44659e764e56SPeter Brune 44669e764e56SPeter Brune Input Parameter: 44679e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 44689e764e56SPeter Brune 44699e764e56SPeter Brune Output Parameter: 44709e764e56SPeter Brune . linesearch - linesearch context 44719e764e56SPeter Brune 44729e764e56SPeter Brune Level: developer 44739e764e56SPeter Brune 44749e764e56SPeter Brune .keywords: SNES, get, linesearch 4475f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch() 44769e764e56SPeter Brune @*/ 4477f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch) 44789e764e56SPeter Brune { 44799e764e56SPeter Brune PetscErrorCode ierr; 44809e764e56SPeter Brune const char *optionsprefix; 44819e764e56SPeter Brune 44829e764e56SPeter Brune PetscFunctionBegin; 44839e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 44849e764e56SPeter Brune PetscValidPointer(linesearch, 2); 44859e764e56SPeter Brune if (!snes->linesearch) { 44869e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 4487f1c6b773SPeter Brune ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr); 4488f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 4489b1dca40bSPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 44909e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 44919e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 44929e764e56SPeter Brune } 44939e764e56SPeter Brune *linesearch = snes->linesearch; 44949e764e56SPeter Brune PetscFunctionReturn(0); 44959e764e56SPeter Brune } 44969e764e56SPeter Brune 449769b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4498c6db04a5SJed Brown #include <mex.h> 449969b4f73cSBarry Smith 45008f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 45018f6e6473SBarry Smith 45020807856dSBarry Smith #undef __FUNCT__ 45030807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 45040807856dSBarry Smith /* 45050807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 45060807856dSBarry Smith SNESSetFunctionMatlab(). 45070807856dSBarry Smith 45080807856dSBarry Smith Collective on SNES 45090807856dSBarry Smith 45100807856dSBarry Smith Input Parameters: 45110807856dSBarry Smith + snes - the SNES context 45120807856dSBarry Smith - x - input vector 45130807856dSBarry Smith 45140807856dSBarry Smith Output Parameter: 45150807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 45160807856dSBarry Smith 45170807856dSBarry Smith Notes: 45180807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 45190807856dSBarry Smith implementations, so most users would not generally call this routine 45200807856dSBarry Smith themselves. 45210807856dSBarry Smith 45220807856dSBarry Smith Level: developer 45230807856dSBarry Smith 45240807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 45250807856dSBarry Smith 45260807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 452761b2408cSBarry Smith */ 45287087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 45290807856dSBarry Smith { 4530e650e774SBarry Smith PetscErrorCode ierr; 45318f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 45328f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 45338f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 453491621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 4535e650e774SBarry Smith 45360807856dSBarry Smith PetscFunctionBegin; 45370807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 45380807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 45390807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 45400807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 45410807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 45420807856dSBarry Smith 45430807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 4544e650e774SBarry Smith 454591621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4546e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4547e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 454891621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 454991621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 455091621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 45518f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 45528f6e6473SBarry Smith prhs[4] = sctx->ctx; 4553b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 4554e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4555e650e774SBarry Smith mxDestroyArray(prhs[0]); 4556e650e774SBarry Smith mxDestroyArray(prhs[1]); 4557e650e774SBarry Smith mxDestroyArray(prhs[2]); 45588f6e6473SBarry Smith mxDestroyArray(prhs[3]); 4559e650e774SBarry Smith mxDestroyArray(plhs[0]); 45600807856dSBarry Smith PetscFunctionReturn(0); 45610807856dSBarry Smith } 45620807856dSBarry Smith 45630807856dSBarry Smith 45640807856dSBarry Smith #undef __FUNCT__ 45650807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 456661b2408cSBarry Smith /* 45670807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 45680807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4569e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 45700807856dSBarry Smith 45710807856dSBarry Smith Logically Collective on SNES 45720807856dSBarry Smith 45730807856dSBarry Smith Input Parameters: 45740807856dSBarry Smith + snes - the SNES context 45750807856dSBarry Smith . r - vector to store function value 45760807856dSBarry Smith - func - function evaluation routine 45770807856dSBarry Smith 45780807856dSBarry Smith Calling sequence of func: 457961b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 45800807856dSBarry Smith 45810807856dSBarry Smith 45820807856dSBarry Smith Notes: 45830807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 45840807856dSBarry Smith $ f'(x) x = -f(x), 45850807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 45860807856dSBarry Smith 45870807856dSBarry Smith Level: beginner 45880807856dSBarry Smith 45890807856dSBarry Smith .keywords: SNES, nonlinear, set, function 45900807856dSBarry Smith 45910807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 459261b2408cSBarry Smith */ 45937087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 45940807856dSBarry Smith { 45950807856dSBarry Smith PetscErrorCode ierr; 45968f6e6473SBarry Smith SNESMatlabContext *sctx; 45970807856dSBarry Smith 45980807856dSBarry Smith PetscFunctionBegin; 45998f6e6473SBarry Smith /* currently sctx is memory bleed */ 46008f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 46018f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 46028f6e6473SBarry Smith /* 46038f6e6473SBarry Smith This should work, but it doesn't 46048f6e6473SBarry Smith sctx->ctx = ctx; 46058f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 46068f6e6473SBarry Smith */ 46078f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 46088f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 46090807856dSBarry Smith PetscFunctionReturn(0); 46100807856dSBarry Smith } 461169b4f73cSBarry Smith 461261b2408cSBarry Smith #undef __FUNCT__ 461361b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 461461b2408cSBarry Smith /* 461561b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 461661b2408cSBarry Smith SNESSetJacobianMatlab(). 461761b2408cSBarry Smith 461861b2408cSBarry Smith Collective on SNES 461961b2408cSBarry Smith 462061b2408cSBarry Smith Input Parameters: 462161b2408cSBarry Smith + snes - the SNES context 462261b2408cSBarry Smith . x - input vector 462361b2408cSBarry Smith . A, B - the matrices 462461b2408cSBarry Smith - ctx - user context 462561b2408cSBarry Smith 462661b2408cSBarry Smith Output Parameter: 462761b2408cSBarry Smith . flag - structure of the matrix 462861b2408cSBarry Smith 462961b2408cSBarry Smith Level: developer 463061b2408cSBarry Smith 463161b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 463261b2408cSBarry Smith 463361b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 463461b2408cSBarry Smith @*/ 46357087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 463661b2408cSBarry Smith { 463761b2408cSBarry Smith PetscErrorCode ierr; 463861b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 463961b2408cSBarry Smith int nlhs = 2,nrhs = 6; 464061b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 464161b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 464261b2408cSBarry Smith 464361b2408cSBarry Smith PetscFunctionBegin; 464461b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 464561b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 464661b2408cSBarry Smith 464761b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 464861b2408cSBarry Smith 464961b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 465061b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 465161b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 465261b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 465361b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 465461b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 465561b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 465661b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 465761b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 465861b2408cSBarry Smith prhs[5] = sctx->ctx; 4659b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 466061b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 466161b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 466261b2408cSBarry Smith mxDestroyArray(prhs[0]); 466361b2408cSBarry Smith mxDestroyArray(prhs[1]); 466461b2408cSBarry Smith mxDestroyArray(prhs[2]); 466561b2408cSBarry Smith mxDestroyArray(prhs[3]); 466661b2408cSBarry Smith mxDestroyArray(prhs[4]); 466761b2408cSBarry Smith mxDestroyArray(plhs[0]); 466861b2408cSBarry Smith mxDestroyArray(plhs[1]); 466961b2408cSBarry Smith PetscFunctionReturn(0); 467061b2408cSBarry Smith } 467161b2408cSBarry Smith 467261b2408cSBarry Smith 467361b2408cSBarry Smith #undef __FUNCT__ 467461b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 467561b2408cSBarry Smith /* 467661b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 467761b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4678e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 467961b2408cSBarry Smith 468061b2408cSBarry Smith Logically Collective on SNES 468161b2408cSBarry Smith 468261b2408cSBarry Smith Input Parameters: 468361b2408cSBarry Smith + snes - the SNES context 468461b2408cSBarry Smith . A,B - Jacobian matrices 468561b2408cSBarry Smith . func - function evaluation routine 468661b2408cSBarry Smith - ctx - user context 468761b2408cSBarry Smith 468861b2408cSBarry Smith Calling sequence of func: 468961b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 469061b2408cSBarry Smith 469161b2408cSBarry Smith 469261b2408cSBarry Smith Level: developer 469361b2408cSBarry Smith 469461b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 469561b2408cSBarry Smith 469661b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 469761b2408cSBarry Smith */ 46987087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 469961b2408cSBarry Smith { 470061b2408cSBarry Smith PetscErrorCode ierr; 470161b2408cSBarry Smith SNESMatlabContext *sctx; 470261b2408cSBarry Smith 470361b2408cSBarry Smith PetscFunctionBegin; 470461b2408cSBarry Smith /* currently sctx is memory bleed */ 470561b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 470661b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 470761b2408cSBarry Smith /* 470861b2408cSBarry Smith This should work, but it doesn't 470961b2408cSBarry Smith sctx->ctx = ctx; 471061b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 471161b2408cSBarry Smith */ 471261b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 471361b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 471461b2408cSBarry Smith PetscFunctionReturn(0); 471561b2408cSBarry Smith } 471669b4f73cSBarry Smith 4717f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4718f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4719f9eb7ae2SShri Abhyankar /* 4720f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4721f9eb7ae2SShri Abhyankar 4722f9eb7ae2SShri Abhyankar Collective on SNES 4723f9eb7ae2SShri Abhyankar 4724f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4725f9eb7ae2SShri Abhyankar @*/ 47267087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4727f9eb7ae2SShri Abhyankar { 4728f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 472948f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4730f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4731f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4732f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4733f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4734f9eb7ae2SShri Abhyankar 4735f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4736f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4737f9eb7ae2SShri Abhyankar 4738f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4739f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4740f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4741f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4742f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4743f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4744f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4745f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4746f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4747f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4748f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4749f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4750f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4751f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4752f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4753f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4754f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4755f9eb7ae2SShri Abhyankar } 4756f9eb7ae2SShri Abhyankar 4757f9eb7ae2SShri Abhyankar 4758f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4759f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4760f9eb7ae2SShri Abhyankar /* 4761e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4762f9eb7ae2SShri Abhyankar 4763f9eb7ae2SShri Abhyankar Level: developer 4764f9eb7ae2SShri Abhyankar 4765f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4766f9eb7ae2SShri Abhyankar 4767f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4768f9eb7ae2SShri Abhyankar */ 47697087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4770f9eb7ae2SShri Abhyankar { 4771f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4772f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4773f9eb7ae2SShri Abhyankar 4774f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4775f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4776f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4777f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4778f9eb7ae2SShri Abhyankar /* 4779f9eb7ae2SShri Abhyankar This should work, but it doesn't 4780f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4781f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4782f9eb7ae2SShri Abhyankar */ 4783f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4784f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4785f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4786f9eb7ae2SShri Abhyankar } 4787f9eb7ae2SShri Abhyankar 478869b4f73cSBarry Smith #endif 4789