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); 1919b94acceSBarry Smith if (snes->ksp_ewconv) { 192fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 1939b94acceSBarry Smith if (kctx) { 19477431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr); 195a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr); 196a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr); 1979b94acceSBarry Smith } 1989b94acceSBarry Smith } 199eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 200eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n");CHKERRQ(ierr); 201eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 202eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr); 203eb1f6c34SBarry Smith } 204eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 205eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n");CHKERRQ(ierr); 206eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 20742f4f86dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr); 208eb1f6c34SBarry Smith } 2090f5bd95cSBarry Smith } else if (isstring) { 210317d6ea6SBarry Smith const char *type; 211454a90a3SBarry Smith ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 212b0a32e0cSBarry Smith ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr); 21319bcc07fSBarry Smith } 21442f4f86dSBarry Smith if (snes->pc && snes->usespc) { 2154a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2164a0c5b0cSMatthew G Knepley ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr); 2174a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2184a0c5b0cSMatthew G Knepley } 2192c155ee1SBarry Smith if (snes->usesksp) { 2202c155ee1SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 221b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 22294b7f48cSBarry Smith ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 223b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2242c155ee1SBarry Smith } 2257f1410a3SPeter Brune if (snes->linesearch) { 2267f1410a3SPeter Brune ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2277f1410a3SPeter Brune ierr = SNESGetSNESLineSearch(snes, &linesearch);CHKERRQ(ierr); 2287f1410a3SPeter Brune ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr); 2297f1410a3SPeter Brune ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2307f1410a3SPeter Brune } 2313a40ed3dSBarry Smith PetscFunctionReturn(0); 2329b94acceSBarry Smith } 2339b94acceSBarry Smith 23476b2cf59SMatthew Knepley /* 23576b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 23676b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 23776b2cf59SMatthew Knepley */ 23876b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 239a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 2406849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 24176b2cf59SMatthew Knepley 242e74ef692SMatthew Knepley #undef __FUNCT__ 243e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker" 244ac226902SBarry Smith /*@C 24576b2cf59SMatthew Knepley SNESAddOptionsChecker - Adds an additional function to check for SNES options. 24676b2cf59SMatthew Knepley 24776b2cf59SMatthew Knepley Not Collective 24876b2cf59SMatthew Knepley 24976b2cf59SMatthew Knepley Input Parameter: 25076b2cf59SMatthew Knepley . snescheck - function that checks for options 25176b2cf59SMatthew Knepley 25276b2cf59SMatthew Knepley Level: developer 25376b2cf59SMatthew Knepley 25476b2cf59SMatthew Knepley .seealso: SNESSetFromOptions() 25576b2cf59SMatthew Knepley @*/ 2567087cfbeSBarry Smith PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 25776b2cf59SMatthew Knepley { 25876b2cf59SMatthew Knepley PetscFunctionBegin; 25976b2cf59SMatthew Knepley if (numberofsetfromoptions >= MAXSETFROMOPTIONS) { 260e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 26176b2cf59SMatthew Knepley } 26276b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 26376b2cf59SMatthew Knepley PetscFunctionReturn(0); 26476b2cf59SMatthew Knepley } 26576b2cf59SMatthew Knepley 2667087cfbeSBarry Smith extern PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 267aa3661deSLisandro Dalcin 268aa3661deSLisandro Dalcin #undef __FUNCT__ 269aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private" 270ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 271aa3661deSLisandro Dalcin { 272aa3661deSLisandro Dalcin Mat J; 273aa3661deSLisandro Dalcin KSP ksp; 274aa3661deSLisandro Dalcin PC pc; 275ace3abfcSBarry Smith PetscBool match; 276aa3661deSLisandro Dalcin PetscErrorCode ierr; 277aa3661deSLisandro Dalcin 278aa3661deSLisandro Dalcin PetscFunctionBegin; 2790700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 280aa3661deSLisandro Dalcin 28198613b67SLisandro Dalcin if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 28298613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 28398613b67SLisandro Dalcin ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr); 28498613b67SLisandro Dalcin } 28598613b67SLisandro Dalcin 286aa3661deSLisandro Dalcin if (version == 1) { 287aa3661deSLisandro Dalcin ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 28898613b67SLisandro Dalcin ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 2899c6ac3b3SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 290aa3661deSLisandro Dalcin } else if (version == 2) { 291e32f2f54SBarry Smith if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 29282a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 293aa3661deSLisandro Dalcin ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr); 294aa3661deSLisandro Dalcin #else 295e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)"); 296aa3661deSLisandro Dalcin #endif 297a8248277SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2"); 298aa3661deSLisandro Dalcin 299aa3661deSLisandro Dalcin ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr); 300d3462f78SMatthew Knepley if (hasOperator) { 301aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 302aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 303aa3661deSLisandro Dalcin ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 304aa3661deSLisandro Dalcin } else { 305aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 306aa3661deSLisandro Dalcin provided preconditioner matrix with the default matrix free version. */ 3076cab3a1bSJed Brown void *functx; 3086cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 3096cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr); 310aa3661deSLisandro Dalcin /* Force no preconditioner */ 311aa3661deSLisandro Dalcin ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 312aa3661deSLisandro Dalcin ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 313251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr); 314aa3661deSLisandro Dalcin if (!match) { 315aa3661deSLisandro Dalcin ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 316aa3661deSLisandro Dalcin ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 317aa3661deSLisandro Dalcin } 318aa3661deSLisandro Dalcin } 3196bf464f9SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 320aa3661deSLisandro Dalcin PetscFunctionReturn(0); 321aa3661deSLisandro Dalcin } 322aa3661deSLisandro Dalcin 3234a2ae208SSatish Balay #undef __FUNCT__ 324dfe15315SJed Brown #define __FUNCT__ "DMRestrictHook_SNESVecSol" 325dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx) 326dfe15315SJed Brown { 327dfe15315SJed Brown SNES snes = (SNES)ctx; 328dfe15315SJed Brown PetscErrorCode ierr; 329dfe15315SJed Brown Vec Xfine,Xfine_named = PETSC_NULL,Xcoarse; 330dfe15315SJed Brown 331dfe15315SJed Brown PetscFunctionBegin; 332dfe15315SJed Brown if (dmfine == snes->dm) Xfine = snes->vec_sol; 333dfe15315SJed Brown else { 334dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr); 335dfe15315SJed Brown Xfine = Xfine_named; 336dfe15315SJed Brown } 337dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 338dfe15315SJed Brown ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr); 339dfe15315SJed Brown ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr); 340dfe15315SJed Brown ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 341dfe15315SJed Brown if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);} 342dfe15315SJed Brown PetscFunctionReturn(0); 343dfe15315SJed Brown } 344dfe15315SJed Brown 345dfe15315SJed Brown #undef __FUNCT__ 346caa4e7f2SJed Brown #define __FUNCT__ "KSPComputeOperators_SNES" 347a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can 348a6950cb2SJed Brown * safely call SNESGetDM() in their residual evaluation routine. */ 349caa4e7f2SJed Brown static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,MatStructure *mstruct,void *ctx) 350caa4e7f2SJed Brown { 351caa4e7f2SJed Brown SNES snes = (SNES)ctx; 352caa4e7f2SJed Brown PetscErrorCode ierr; 353caa4e7f2SJed Brown Mat Asave = A,Bsave = B; 354dfe15315SJed Brown Vec X,Xnamed = PETSC_NULL; 355dfe15315SJed Brown DM dmsave; 356caa4e7f2SJed Brown 357caa4e7f2SJed Brown PetscFunctionBegin; 358dfe15315SJed Brown dmsave = snes->dm; 359dfe15315SJed Brown ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr); 360dfe15315SJed Brown if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */ 361dfe15315SJed Brown else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ 362dfe15315SJed Brown ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 363dfe15315SJed Brown X = Xnamed; 364dfe15315SJed Brown } 365dfe15315SJed Brown ierr = SNESComputeJacobian(snes,X,&A,&B,mstruct);CHKERRQ(ierr); 366caa4e7f2SJed Brown if (A != Asave || B != Bsave) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"No support for changing matrices at this time"); 367dfe15315SJed Brown if (Xnamed) { 368dfe15315SJed Brown ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 369dfe15315SJed Brown } 370dfe15315SJed Brown snes->dm = dmsave; 371caa4e7f2SJed Brown PetscFunctionReturn(0); 372caa4e7f2SJed Brown } 373caa4e7f2SJed Brown 374caa4e7f2SJed Brown #undef __FUNCT__ 3756cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices" 3766cab3a1bSJed Brown /*@ 3776cab3a1bSJed Brown SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX() 3786cab3a1bSJed Brown 3796cab3a1bSJed Brown Collective 3806cab3a1bSJed Brown 3816cab3a1bSJed Brown Input Arguments: 3826cab3a1bSJed Brown . snes - snes to configure 3836cab3a1bSJed Brown 3846cab3a1bSJed Brown Level: developer 3856cab3a1bSJed Brown 3866cab3a1bSJed Brown .seealso: SNESSetUp() 3876cab3a1bSJed Brown @*/ 3886cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes) 3896cab3a1bSJed Brown { 3906cab3a1bSJed Brown PetscErrorCode ierr; 3916cab3a1bSJed Brown DM dm; 3926cab3a1bSJed Brown SNESDM sdm; 3936cab3a1bSJed Brown 3946cab3a1bSJed Brown PetscFunctionBegin; 3956cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3966cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 397caa4e7f2SJed Brown if (!sdm->computejacobian) { 39817842b4fSJed Brown SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_PLIB,"SNESDM not improperly configured"); 3996cab3a1bSJed Brown } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) { 4006cab3a1bSJed Brown Mat J; 4016cab3a1bSJed Brown void *functx; 4026cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4036cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4046cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4056cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 4066cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr); 4076cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 408caa4e7f2SJed Brown } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 4096cab3a1bSJed Brown Mat J,B; 4106cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4116cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4126cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4136cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 41406f20277SJed Brown /* sdm->computejacobian was already set to reach here */ 41506f20277SJed Brown ierr = SNESSetJacobian(snes,J,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 4166cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 4176cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 418caa4e7f2SJed Brown } else if (!snes->jacobian_pre) { 4196cab3a1bSJed Brown Mat J,B; 4206cab3a1bSJed Brown J = snes->jacobian; 4216cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 4226cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 4236cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 4246cab3a1bSJed Brown } 425caa4e7f2SJed Brown { 42660a3618bSJed Brown PetscBool flg = PETSC_FALSE; 427caa4e7f2SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_kspcompute",&flg,PETSC_NULL);CHKERRQ(ierr); 428caa4e7f2SJed Brown if (flg) { /* Plan to transition to this model */ 429caa4e7f2SJed Brown KSP ksp; 430caa4e7f2SJed Brown ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 431caa4e7f2SJed Brown ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr); 432dfe15315SJed Brown ierr = DMCoarsenHookAdd(snes->dm,PETSC_NULL,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 433caa4e7f2SJed Brown } 434caa4e7f2SJed Brown } 4356cab3a1bSJed Brown PetscFunctionReturn(0); 4366cab3a1bSJed Brown } 4376cab3a1bSJed Brown 4386cab3a1bSJed Brown #undef __FUNCT__ 4394a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions" 4409b94acceSBarry Smith /*@ 44194b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 4429b94acceSBarry Smith 443c7afd0dbSLois Curfman McInnes Collective on SNES 444c7afd0dbSLois Curfman McInnes 4459b94acceSBarry Smith Input Parameter: 4469b94acceSBarry Smith . snes - the SNES context 4479b94acceSBarry Smith 44836851e7fSLois Curfman McInnes Options Database Keys: 449ea630c6eSPeter Brune + -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas 45082738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 45182738288SBarry Smith of the change in the solution between steps 45270441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 453b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 454b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 455b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 4564839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 457ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 458a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 459e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 460b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 4612492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 46282738288SBarry Smith solver; hence iterations will continue until max_it 4631fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 46482738288SBarry Smith of convergence test 465e8105e01SRichard Katz . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 466e8105e01SRichard Katz filename given prints to stdout 467a6570f20SBarry Smith . -snes_monitor_solution - plots solution at each iteration 468a6570f20SBarry Smith . -snes_monitor_residual - plots residual (not its norm) at each iteration 469a6570f20SBarry Smith . -snes_monitor_solution_update - plots update to solution at each iteration 470a6570f20SBarry Smith . -snes_monitor_draw - plots residual norm at each iteration 471e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 4725968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 473fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 47482738288SBarry Smith 47582738288SBarry Smith Options Database for Eisenstat-Walker method: 476fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 4774b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 47836851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 47936851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 48036851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 48136851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 48236851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 48336851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 48482738288SBarry Smith 48511ca99fdSLois Curfman McInnes Notes: 48611ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 4870598bfebSBarry Smith the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>. 48883e2fdc7SBarry Smith 48936851e7fSLois Curfman McInnes Level: beginner 49036851e7fSLois Curfman McInnes 4919b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 4929b94acceSBarry Smith 49369ed319cSSatish Balay .seealso: SNESSetOptionsPrefix() 4949b94acceSBarry Smith @*/ 4957087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 4969b94acceSBarry Smith { 497872b6db9SPeter Brune PetscBool flg,mf,mf_operator,pcset; 498efd51863SBarry Smith PetscInt i,indx,lag,mf_version,grids; 499aa3661deSLisandro Dalcin MatStructure matflag; 50085385478SLisandro Dalcin const char *deft = SNESLS; 50185385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 50285385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 503e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 504649052a6SBarry Smith PetscViewer monviewer; 50585385478SLisandro Dalcin PetscErrorCode ierr; 506a64e098fSPeter Brune const char *optionsprefix; 5079b94acceSBarry Smith 5083a40ed3dSBarry Smith PetscFunctionBegin; 5090700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 510ca161407SBarry Smith 511186905e3SBarry Smith if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 5123194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 5137adad957SLisandro Dalcin if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; } 514b0a32e0cSBarry Smith ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 515d64ed03dSBarry Smith if (flg) { 516186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 5177adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 518186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 519d64ed03dSBarry Smith } 52090d69ab7SBarry Smith /* not used here, but called so will go into help messaage */ 521909c8a9fSBarry Smith ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 52293c39befSBarry Smith 523c60f73f4SPeter Brune ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr); 52457034d6fSHong Zhang ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 525186905e3SBarry Smith 52657034d6fSHong Zhang ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 527b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 528b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 52924254dc1SJed Brown ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 530ddf469c8SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr); 531acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr); 53285385478SLisandro Dalcin 533a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 534a8054027SBarry Smith if (flg) { 535a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 536a8054027SBarry Smith } 537e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 538e35cf81dSBarry Smith if (flg) { 539e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 540e35cf81dSBarry Smith } 541efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 542efd51863SBarry Smith if (flg) { 543efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 544efd51863SBarry Smith } 545a8054027SBarry Smith 54685385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 54785385478SLisandro Dalcin if (flg) { 54885385478SLisandro Dalcin switch (indx) { 5497f7931b9SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 5507f7931b9SBarry Smith case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 55185385478SLisandro Dalcin } 55285385478SLisandro Dalcin } 55385385478SLisandro Dalcin 554acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr); 555186905e3SBarry Smith 556fdacfa88SPeter Brune ierr = PetscOptionsEList("-snes_norm_type","SNES Norm type","SNESSetNormType",SNESNormTypes,5,"function",&indx,&flg);CHKERRQ(ierr); 557fdacfa88SPeter Brune if (flg) { ierr = SNESSetNormType(snes,(SNESNormType)indx);CHKERRQ(ierr); } 558fdacfa88SPeter Brune 55985385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 56085385478SLisandro Dalcin 561acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 562186905e3SBarry Smith 563fa9f3622SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 564fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 565fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 566fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 567fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 568fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 569fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 570186905e3SBarry Smith 57190d69ab7SBarry Smith flg = PETSC_FALSE; 572acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 573a6570f20SBarry Smith if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 574eabae89aSBarry Smith 575a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 576e8105e01SRichard Katz if (flg) { 577649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 578649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 579e8105e01SRichard Katz } 580eabae89aSBarry Smith 581b271bb04SBarry Smith ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 582b271bb04SBarry Smith if (flg) { 583b271bb04SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 584b271bb04SBarry Smith } 585b271bb04SBarry Smith 586a6570f20SBarry Smith ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 587eabae89aSBarry Smith if (flg) { 588649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 589f1bef1bcSMatthew Knepley ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 590e8105e01SRichard Katz } 591eabae89aSBarry Smith 592a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 593eabae89aSBarry Smith if (flg) { 594649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 595649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 596eabae89aSBarry Smith } 597eabae89aSBarry Smith 5985180491cSLisandro Dalcin ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 5995180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 6005180491cSLisandro Dalcin 60190d69ab7SBarry Smith flg = PETSC_FALSE; 602acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 603a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 60490d69ab7SBarry Smith flg = PETSC_FALSE; 605acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 606a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 60790d69ab7SBarry Smith flg = PETSC_FALSE; 608acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 609a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 61090d69ab7SBarry Smith flg = PETSC_FALSE; 611acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 612a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 61390d69ab7SBarry Smith flg = PETSC_FALSE; 614acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 615b271bb04SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 616e24b481bSBarry Smith 61790d69ab7SBarry Smith flg = PETSC_FALSE; 618acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 6194b27c08aSLois Curfman McInnes if (flg) { 6206cab3a1bSJed Brown void *functx; 6216cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 6226cab3a1bSJed Brown ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr); 623ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 6249b94acceSBarry Smith } 625639f9d9dSBarry Smith 626aa3661deSLisandro Dalcin mf = mf_operator = PETSC_FALSE; 627aa3661deSLisandro Dalcin flg = PETSC_FALSE; 628acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr); 629a8248277SBarry Smith if (flg && mf_operator) { 630a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 631a8248277SBarry Smith mf = PETSC_TRUE; 632a8248277SBarry Smith } 633aa3661deSLisandro Dalcin flg = PETSC_FALSE; 634acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr); 635aa3661deSLisandro Dalcin if (!flg && mf_operator) mf = PETSC_TRUE; 636aa3661deSLisandro Dalcin mf_version = 1; 637aa3661deSLisandro Dalcin ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr); 638aa3661deSLisandro Dalcin 639d28543b3SPeter Brune 64089b92e6fSPeter Brune /* GS Options */ 64189b92e6fSPeter Brune ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr); 64289b92e6fSPeter Brune 64376b2cf59SMatthew Knepley for(i = 0; i < numberofsetfromoptions; i++) { 64476b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 64576b2cf59SMatthew Knepley } 64676b2cf59SMatthew Knepley 647e7788613SBarry Smith if (snes->ops->setfromoptions) { 648e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 649639f9d9dSBarry Smith } 6505d973c19SBarry Smith 6515d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 6525d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 653b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 6544bbc92c1SBarry Smith 655aa3661deSLisandro Dalcin if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 6561cee3971SBarry Smith 6571cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 658aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 659aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 66085385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 66193993e2dSLois Curfman McInnes 6629e764e56SPeter Brune if (!snes->linesearch) { 663f1c6b773SPeter Brune ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 6649e764e56SPeter Brune } 665f1c6b773SPeter Brune ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr); 6669e764e56SPeter Brune 66751e86f29SPeter Brune /* if someone has set the SNES PC type, create it. */ 66851e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 66951e86f29SPeter Brune ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 67051e86f29SPeter Brune if (pcset && (!snes->pc)) { 67151e86f29SPeter Brune ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr); 67251e86f29SPeter Brune } 6733a40ed3dSBarry Smith PetscFunctionReturn(0); 6749b94acceSBarry Smith } 6759b94acceSBarry Smith 676d25893d9SBarry Smith #undef __FUNCT__ 677d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 678d25893d9SBarry Smith /*@ 679d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 680d25893d9SBarry Smith the nonlinear solvers. 681d25893d9SBarry Smith 682d25893d9SBarry Smith Logically Collective on SNES 683d25893d9SBarry Smith 684d25893d9SBarry Smith Input Parameters: 685d25893d9SBarry Smith + snes - the SNES context 686d25893d9SBarry Smith . compute - function to compute the context 687d25893d9SBarry Smith - destroy - function to destroy the context 688d25893d9SBarry Smith 689d25893d9SBarry Smith Level: intermediate 690d25893d9SBarry Smith 691d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 692d25893d9SBarry Smith 693d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 694d25893d9SBarry Smith @*/ 695d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 696d25893d9SBarry Smith { 697d25893d9SBarry Smith PetscFunctionBegin; 698d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 699d25893d9SBarry Smith snes->ops->usercompute = compute; 700d25893d9SBarry Smith snes->ops->userdestroy = destroy; 701d25893d9SBarry Smith PetscFunctionReturn(0); 702d25893d9SBarry Smith } 703a847f771SSatish Balay 7044a2ae208SSatish Balay #undef __FUNCT__ 7054a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 706b07ff414SBarry Smith /*@ 7079b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 7089b94acceSBarry Smith the nonlinear solvers. 7099b94acceSBarry Smith 7103f9fe445SBarry Smith Logically Collective on SNES 711fee21e36SBarry Smith 712c7afd0dbSLois Curfman McInnes Input Parameters: 713c7afd0dbSLois Curfman McInnes + snes - the SNES context 714c7afd0dbSLois Curfman McInnes - usrP - optional user context 715c7afd0dbSLois Curfman McInnes 71636851e7fSLois Curfman McInnes Level: intermediate 71736851e7fSLois Curfman McInnes 7189b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 7199b94acceSBarry Smith 720ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext() 7219b94acceSBarry Smith @*/ 7227087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 7239b94acceSBarry Smith { 7241b2093e4SBarry Smith PetscErrorCode ierr; 725b07ff414SBarry Smith KSP ksp; 7261b2093e4SBarry Smith 7273a40ed3dSBarry Smith PetscFunctionBegin; 7280700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 729b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 730b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 7319b94acceSBarry Smith snes->user = usrP; 7323a40ed3dSBarry Smith PetscFunctionReturn(0); 7339b94acceSBarry Smith } 73474679c65SBarry Smith 7354a2ae208SSatish Balay #undef __FUNCT__ 7364a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 737b07ff414SBarry Smith /*@ 7389b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 7399b94acceSBarry Smith nonlinear solvers. 7409b94acceSBarry Smith 741c7afd0dbSLois Curfman McInnes Not Collective 742c7afd0dbSLois Curfman McInnes 7439b94acceSBarry Smith Input Parameter: 7449b94acceSBarry Smith . snes - SNES context 7459b94acceSBarry Smith 7469b94acceSBarry Smith Output Parameter: 7479b94acceSBarry Smith . usrP - user context 7489b94acceSBarry Smith 74936851e7fSLois Curfman McInnes Level: intermediate 75036851e7fSLois Curfman McInnes 7519b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 7529b94acceSBarry Smith 7539b94acceSBarry Smith .seealso: SNESSetApplicationContext() 7549b94acceSBarry Smith @*/ 755e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 7569b94acceSBarry Smith { 7573a40ed3dSBarry Smith PetscFunctionBegin; 7580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 759e71120c6SJed Brown *(void**)usrP = snes->user; 7603a40ed3dSBarry Smith PetscFunctionReturn(0); 7619b94acceSBarry Smith } 76274679c65SBarry Smith 7634a2ae208SSatish Balay #undef __FUNCT__ 7644a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 7659b94acceSBarry Smith /*@ 766c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 767c8228a4eSBarry Smith at this time. 7689b94acceSBarry Smith 769c7afd0dbSLois Curfman McInnes Not Collective 770c7afd0dbSLois Curfman McInnes 7719b94acceSBarry Smith Input Parameter: 7729b94acceSBarry Smith . snes - SNES context 7739b94acceSBarry Smith 7749b94acceSBarry Smith Output Parameter: 7759b94acceSBarry Smith . iter - iteration number 7769b94acceSBarry Smith 777c8228a4eSBarry Smith Notes: 778c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 779c8228a4eSBarry Smith 780c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 78108405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 78208405cd6SLois Curfman McInnes .vb 78308405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 78408405cd6SLois Curfman McInnes if (!(it % 2)) { 78508405cd6SLois Curfman McInnes [compute Jacobian here] 78608405cd6SLois Curfman McInnes } 78708405cd6SLois Curfman McInnes .ve 788c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 78908405cd6SLois Curfman McInnes recomputed every second SNES iteration. 790c8228a4eSBarry Smith 79136851e7fSLois Curfman McInnes Level: intermediate 79236851e7fSLois Curfman McInnes 7932b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 7942b668275SBarry Smith 795b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 7969b94acceSBarry Smith @*/ 7977087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 7989b94acceSBarry Smith { 7993a40ed3dSBarry Smith PetscFunctionBegin; 8000700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8014482741eSBarry Smith PetscValidIntPointer(iter,2); 8029b94acceSBarry Smith *iter = snes->iter; 8033a40ed3dSBarry Smith PetscFunctionReturn(0); 8049b94acceSBarry Smith } 80574679c65SBarry Smith 8064a2ae208SSatish Balay #undef __FUNCT__ 807360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber" 808360c497dSPeter Brune /*@ 809360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 810360c497dSPeter Brune 811360c497dSPeter Brune Not Collective 812360c497dSPeter Brune 813360c497dSPeter Brune Input Parameter: 814360c497dSPeter Brune . snes - SNES context 815360c497dSPeter Brune . iter - iteration number 816360c497dSPeter Brune 817360c497dSPeter Brune Level: developer 818360c497dSPeter Brune 819360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number, 820360c497dSPeter Brune 821360c497dSPeter Brune .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 822360c497dSPeter Brune @*/ 823360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 824360c497dSPeter Brune { 825360c497dSPeter Brune PetscErrorCode ierr; 826360c497dSPeter Brune 827360c497dSPeter Brune PetscFunctionBegin; 828360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 829360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 830360c497dSPeter Brune snes->iter = iter; 831360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 832360c497dSPeter Brune PetscFunctionReturn(0); 833360c497dSPeter Brune } 834360c497dSPeter Brune 835360c497dSPeter Brune #undef __FUNCT__ 8364a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 8379b94acceSBarry Smith /*@ 8389b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 8399b94acceSBarry Smith with SNESSSetFunction(). 8409b94acceSBarry Smith 841c7afd0dbSLois Curfman McInnes Collective on SNES 842c7afd0dbSLois Curfman McInnes 8439b94acceSBarry Smith Input Parameter: 8449b94acceSBarry Smith . snes - SNES context 8459b94acceSBarry Smith 8469b94acceSBarry Smith Output Parameter: 8479b94acceSBarry Smith . fnorm - 2-norm of function 8489b94acceSBarry Smith 84936851e7fSLois Curfman McInnes Level: intermediate 85036851e7fSLois Curfman McInnes 8519b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 852a86d99e1SLois Curfman McInnes 853b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 8549b94acceSBarry Smith @*/ 8557087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 8569b94acceSBarry Smith { 8573a40ed3dSBarry Smith PetscFunctionBegin; 8580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8594482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 8609b94acceSBarry Smith *fnorm = snes->norm; 8613a40ed3dSBarry Smith PetscFunctionReturn(0); 8629b94acceSBarry Smith } 86374679c65SBarry Smith 864360c497dSPeter Brune 865360c497dSPeter Brune #undef __FUNCT__ 866360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm" 867360c497dSPeter Brune /*@ 868360c497dSPeter Brune SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm(). 869360c497dSPeter Brune 870360c497dSPeter Brune Collective on SNES 871360c497dSPeter Brune 872360c497dSPeter Brune Input Parameter: 873360c497dSPeter Brune . snes - SNES context 874360c497dSPeter Brune . fnorm - 2-norm of function 875360c497dSPeter Brune 876360c497dSPeter Brune Level: developer 877360c497dSPeter Brune 878360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm 879360c497dSPeter Brune 880360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm(). 881360c497dSPeter Brune @*/ 882360c497dSPeter Brune PetscErrorCode SNESSetFunctionNorm(SNES snes,PetscReal fnorm) 883360c497dSPeter Brune { 884360c497dSPeter Brune 885360c497dSPeter Brune PetscErrorCode ierr; 886360c497dSPeter Brune 887360c497dSPeter Brune PetscFunctionBegin; 888360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 889360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 890360c497dSPeter Brune snes->norm = fnorm; 891360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 892360c497dSPeter Brune PetscFunctionReturn(0); 893360c497dSPeter Brune } 894360c497dSPeter Brune 8954a2ae208SSatish Balay #undef __FUNCT__ 896b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 8979b94acceSBarry Smith /*@ 898b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 8999b94acceSBarry Smith attempted by the nonlinear solver. 9009b94acceSBarry Smith 901c7afd0dbSLois Curfman McInnes Not Collective 902c7afd0dbSLois Curfman McInnes 9039b94acceSBarry Smith Input Parameter: 9049b94acceSBarry Smith . snes - SNES context 9059b94acceSBarry Smith 9069b94acceSBarry Smith Output Parameter: 9079b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 9089b94acceSBarry Smith 909c96a6f78SLois Curfman McInnes Notes: 910c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 911c96a6f78SLois Curfman McInnes 91236851e7fSLois Curfman McInnes Level: intermediate 91336851e7fSLois Curfman McInnes 9149b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 91558ebbce7SBarry Smith 916e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 91758ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 9189b94acceSBarry Smith @*/ 9197087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 9209b94acceSBarry Smith { 9213a40ed3dSBarry Smith PetscFunctionBegin; 9220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9234482741eSBarry Smith PetscValidIntPointer(nfails,2); 92450ffb88aSMatthew Knepley *nfails = snes->numFailures; 92550ffb88aSMatthew Knepley PetscFunctionReturn(0); 92650ffb88aSMatthew Knepley } 92750ffb88aSMatthew Knepley 92850ffb88aSMatthew Knepley #undef __FUNCT__ 929b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 93050ffb88aSMatthew Knepley /*@ 931b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 93250ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 93350ffb88aSMatthew Knepley 93450ffb88aSMatthew Knepley Not Collective 93550ffb88aSMatthew Knepley 93650ffb88aSMatthew Knepley Input Parameters: 93750ffb88aSMatthew Knepley + snes - SNES context 93850ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 93950ffb88aSMatthew Knepley 94050ffb88aSMatthew Knepley Level: intermediate 94150ffb88aSMatthew Knepley 94250ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 94358ebbce7SBarry Smith 944e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 94558ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 94650ffb88aSMatthew Knepley @*/ 9477087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 94850ffb88aSMatthew Knepley { 94950ffb88aSMatthew Knepley PetscFunctionBegin; 9500700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 95150ffb88aSMatthew Knepley snes->maxFailures = maxFails; 95250ffb88aSMatthew Knepley PetscFunctionReturn(0); 95350ffb88aSMatthew Knepley } 95450ffb88aSMatthew Knepley 95550ffb88aSMatthew Knepley #undef __FUNCT__ 956b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 95750ffb88aSMatthew Knepley /*@ 958b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 95950ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 96050ffb88aSMatthew Knepley 96150ffb88aSMatthew Knepley Not Collective 96250ffb88aSMatthew Knepley 96350ffb88aSMatthew Knepley Input Parameter: 96450ffb88aSMatthew Knepley . snes - SNES context 96550ffb88aSMatthew Knepley 96650ffb88aSMatthew Knepley Output Parameter: 96750ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 96850ffb88aSMatthew Knepley 96950ffb88aSMatthew Knepley Level: intermediate 97050ffb88aSMatthew Knepley 97150ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 97258ebbce7SBarry Smith 973e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 97458ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 97558ebbce7SBarry Smith 97650ffb88aSMatthew Knepley @*/ 9777087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 97850ffb88aSMatthew Knepley { 97950ffb88aSMatthew Knepley PetscFunctionBegin; 9800700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9814482741eSBarry Smith PetscValidIntPointer(maxFails,2); 98250ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 9833a40ed3dSBarry Smith PetscFunctionReturn(0); 9849b94acceSBarry Smith } 985a847f771SSatish Balay 9864a2ae208SSatish Balay #undef __FUNCT__ 9872541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 9882541af92SBarry Smith /*@ 9892541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 9902541af92SBarry Smith done by SNES. 9912541af92SBarry Smith 9922541af92SBarry Smith Not Collective 9932541af92SBarry Smith 9942541af92SBarry Smith Input Parameter: 9952541af92SBarry Smith . snes - SNES context 9962541af92SBarry Smith 9972541af92SBarry Smith Output Parameter: 9982541af92SBarry Smith . nfuncs - number of evaluations 9992541af92SBarry Smith 10002541af92SBarry Smith Level: intermediate 10012541af92SBarry Smith 10022541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 100358ebbce7SBarry Smith 1004e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 10052541af92SBarry Smith @*/ 10067087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 10072541af92SBarry Smith { 10082541af92SBarry Smith PetscFunctionBegin; 10090700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10102541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 10112541af92SBarry Smith *nfuncs = snes->nfuncs; 10122541af92SBarry Smith PetscFunctionReturn(0); 10132541af92SBarry Smith } 10142541af92SBarry Smith 10152541af92SBarry Smith #undef __FUNCT__ 10163d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 10173d4c4710SBarry Smith /*@ 10183d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 10193d4c4710SBarry Smith linear solvers. 10203d4c4710SBarry Smith 10213d4c4710SBarry Smith Not Collective 10223d4c4710SBarry Smith 10233d4c4710SBarry Smith Input Parameter: 10243d4c4710SBarry Smith . snes - SNES context 10253d4c4710SBarry Smith 10263d4c4710SBarry Smith Output Parameter: 10273d4c4710SBarry Smith . nfails - number of failed solves 10283d4c4710SBarry Smith 10293d4c4710SBarry Smith Notes: 10303d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 10313d4c4710SBarry Smith 10323d4c4710SBarry Smith Level: intermediate 10333d4c4710SBarry Smith 10343d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 103558ebbce7SBarry Smith 1036e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 10373d4c4710SBarry Smith @*/ 10387087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 10393d4c4710SBarry Smith { 10403d4c4710SBarry Smith PetscFunctionBegin; 10410700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10423d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 10433d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 10443d4c4710SBarry Smith PetscFunctionReturn(0); 10453d4c4710SBarry Smith } 10463d4c4710SBarry Smith 10473d4c4710SBarry Smith #undef __FUNCT__ 10483d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 10493d4c4710SBarry Smith /*@ 10503d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 10513d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 10523d4c4710SBarry Smith 10533f9fe445SBarry Smith Logically Collective on SNES 10543d4c4710SBarry Smith 10553d4c4710SBarry Smith Input Parameters: 10563d4c4710SBarry Smith + snes - SNES context 10573d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 10583d4c4710SBarry Smith 10593d4c4710SBarry Smith Level: intermediate 10603d4c4710SBarry Smith 1061a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 10623d4c4710SBarry Smith 10633d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 10643d4c4710SBarry Smith 106558ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 10663d4c4710SBarry Smith @*/ 10677087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 10683d4c4710SBarry Smith { 10693d4c4710SBarry Smith PetscFunctionBegin; 10700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1071c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 10723d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 10733d4c4710SBarry Smith PetscFunctionReturn(0); 10743d4c4710SBarry Smith } 10753d4c4710SBarry Smith 10763d4c4710SBarry Smith #undef __FUNCT__ 10773d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 10783d4c4710SBarry Smith /*@ 10793d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 10803d4c4710SBarry Smith are allowed before SNES terminates 10813d4c4710SBarry Smith 10823d4c4710SBarry Smith Not Collective 10833d4c4710SBarry Smith 10843d4c4710SBarry Smith Input Parameter: 10853d4c4710SBarry Smith . snes - SNES context 10863d4c4710SBarry Smith 10873d4c4710SBarry Smith Output Parameter: 10883d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 10893d4c4710SBarry Smith 10903d4c4710SBarry Smith Level: intermediate 10913d4c4710SBarry Smith 10923d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 10933d4c4710SBarry Smith 10943d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 10953d4c4710SBarry Smith 1096e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 10973d4c4710SBarry Smith @*/ 10987087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 10993d4c4710SBarry Smith { 11003d4c4710SBarry Smith PetscFunctionBegin; 11010700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11023d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 11033d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 11043d4c4710SBarry Smith PetscFunctionReturn(0); 11053d4c4710SBarry Smith } 11063d4c4710SBarry Smith 11073d4c4710SBarry Smith #undef __FUNCT__ 1108b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 1109c96a6f78SLois Curfman McInnes /*@ 1110b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1111c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1112c96a6f78SLois Curfman McInnes 1113c7afd0dbSLois Curfman McInnes Not Collective 1114c7afd0dbSLois Curfman McInnes 1115c96a6f78SLois Curfman McInnes Input Parameter: 1116c96a6f78SLois Curfman McInnes . snes - SNES context 1117c96a6f78SLois Curfman McInnes 1118c96a6f78SLois Curfman McInnes Output Parameter: 1119c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1120c96a6f78SLois Curfman McInnes 1121c96a6f78SLois Curfman McInnes Notes: 1122c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1123c96a6f78SLois Curfman McInnes 112436851e7fSLois Curfman McInnes Level: intermediate 112536851e7fSLois Curfman McInnes 1126c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 11272b668275SBarry Smith 11288c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 1129c96a6f78SLois Curfman McInnes @*/ 11307087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 1131c96a6f78SLois Curfman McInnes { 11323a40ed3dSBarry Smith PetscFunctionBegin; 11330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11344482741eSBarry Smith PetscValidIntPointer(lits,2); 1135c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 11363a40ed3dSBarry Smith PetscFunctionReturn(0); 1137c96a6f78SLois Curfman McInnes } 1138c96a6f78SLois Curfman McInnes 11394a2ae208SSatish Balay #undef __FUNCT__ 114094b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 114152baeb72SSatish Balay /*@ 114294b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 11439b94acceSBarry Smith 114494b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 1145c7afd0dbSLois Curfman McInnes 11469b94acceSBarry Smith Input Parameter: 11479b94acceSBarry Smith . snes - the SNES context 11489b94acceSBarry Smith 11499b94acceSBarry Smith Output Parameter: 115094b7f48cSBarry Smith . ksp - the KSP context 11519b94acceSBarry Smith 11529b94acceSBarry Smith Notes: 115394b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 11549b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 11552999313aSBarry Smith PC contexts as well. 11569b94acceSBarry Smith 115736851e7fSLois Curfman McInnes Level: beginner 115836851e7fSLois Curfman McInnes 115994b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 11609b94acceSBarry Smith 11612999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 11629b94acceSBarry Smith @*/ 11637087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 11649b94acceSBarry Smith { 11651cee3971SBarry Smith PetscErrorCode ierr; 11661cee3971SBarry Smith 11673a40ed3dSBarry Smith PetscFunctionBegin; 11680700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11694482741eSBarry Smith PetscValidPointer(ksp,2); 11701cee3971SBarry Smith 11711cee3971SBarry Smith if (!snes->ksp) { 11721cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 11731cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 11741cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 11751cee3971SBarry Smith } 117694b7f48cSBarry Smith *ksp = snes->ksp; 11773a40ed3dSBarry Smith PetscFunctionReturn(0); 11789b94acceSBarry Smith } 117982bf6240SBarry Smith 11804a2ae208SSatish Balay #undef __FUNCT__ 11812999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 11822999313aSBarry Smith /*@ 11832999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 11842999313aSBarry Smith 11852999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 11862999313aSBarry Smith 11872999313aSBarry Smith Input Parameters: 11882999313aSBarry Smith + snes - the SNES context 11892999313aSBarry Smith - ksp - the KSP context 11902999313aSBarry Smith 11912999313aSBarry Smith Notes: 11922999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 11932999313aSBarry Smith so this routine is rarely needed. 11942999313aSBarry Smith 11952999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 11962999313aSBarry Smith decreased by one. 11972999313aSBarry Smith 11982999313aSBarry Smith Level: developer 11992999313aSBarry Smith 12002999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 12012999313aSBarry Smith 12022999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 12032999313aSBarry Smith @*/ 12047087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 12052999313aSBarry Smith { 12062999313aSBarry Smith PetscErrorCode ierr; 12072999313aSBarry Smith 12082999313aSBarry Smith PetscFunctionBegin; 12090700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12100700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 12112999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 12127dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1213906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 12142999313aSBarry Smith snes->ksp = ksp; 12152999313aSBarry Smith PetscFunctionReturn(0); 12162999313aSBarry Smith } 12172999313aSBarry Smith 12187adad957SLisandro Dalcin #if 0 12192999313aSBarry Smith #undef __FUNCT__ 12204a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 12216849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1222e24b481bSBarry Smith { 1223e24b481bSBarry Smith PetscFunctionBegin; 1224e24b481bSBarry Smith PetscFunctionReturn(0); 1225e24b481bSBarry Smith } 12267adad957SLisandro Dalcin #endif 1227e24b481bSBarry Smith 12289b94acceSBarry Smith /* -----------------------------------------------------------*/ 12294a2ae208SSatish Balay #undef __FUNCT__ 12304a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 123152baeb72SSatish Balay /*@ 12329b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 12339b94acceSBarry Smith 1234c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1235c7afd0dbSLois Curfman McInnes 1236c7afd0dbSLois Curfman McInnes Input Parameters: 1237906ed7ccSBarry Smith . comm - MPI communicator 12389b94acceSBarry Smith 12399b94acceSBarry Smith Output Parameter: 12409b94acceSBarry Smith . outsnes - the new SNES context 12419b94acceSBarry Smith 1242c7afd0dbSLois Curfman McInnes Options Database Keys: 1243c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1244c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1245c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1246c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1247c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1248c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1249c1f60f51SBarry Smith 125036851e7fSLois Curfman McInnes Level: beginner 125136851e7fSLois Curfman McInnes 12529b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 12539b94acceSBarry Smith 1254a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1255a8054027SBarry Smith 12569b94acceSBarry Smith @*/ 12577087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 12589b94acceSBarry Smith { 1259dfbe8321SBarry Smith PetscErrorCode ierr; 12609b94acceSBarry Smith SNES snes; 1261fa9f3622SBarry Smith SNESKSPEW *kctx; 126237fcc0dbSBarry Smith 12633a40ed3dSBarry Smith PetscFunctionBegin; 1264ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 12658ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 12668ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 12678ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 12688ba1e511SMatthew Knepley #endif 12698ba1e511SMatthew Knepley 12703194b578SJed Brown ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 12717adad957SLisandro Dalcin 127285385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 12732c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 127488976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 12759b94acceSBarry Smith snes->max_its = 50; 12769750a799SBarry Smith snes->max_funcs = 10000; 12779b94acceSBarry Smith snes->norm = 0.0; 1278fdacfa88SPeter Brune snes->normtype = SNES_NORM_FUNCTION; 1279b4874afaSBarry Smith snes->rtol = 1.e-8; 1280b4874afaSBarry Smith snes->ttol = 0.0; 128170441072SBarry Smith snes->abstol = 1.e-50; 1282c60f73f4SPeter Brune snes->stol = 1.e-8; 12834b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 12849b94acceSBarry Smith snes->nfuncs = 0; 128550ffb88aSMatthew Knepley snes->numFailures = 0; 128650ffb88aSMatthew Knepley snes->maxFailures = 1; 12877a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1288e35cf81dSBarry Smith snes->lagjacobian = 1; 1289a8054027SBarry Smith snes->lagpreconditioner = 1; 1290639f9d9dSBarry Smith snes->numbermonitors = 0; 12919b94acceSBarry Smith snes->data = 0; 12924dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1293186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 12946f24a144SLois Curfman McInnes snes->nwork = 0; 129558c9b817SLisandro Dalcin snes->work = 0; 129658c9b817SLisandro Dalcin snes->nvwork = 0; 129758c9b817SLisandro Dalcin snes->vwork = 0; 1298758f92a0SBarry Smith snes->conv_hist_len = 0; 1299758f92a0SBarry Smith snes->conv_hist_max = 0; 1300758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1301758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1302758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1303e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1304e4ed7901SPeter Brune snes->norm_init = 0.; 1305e4ed7901SPeter Brune snes->norm_init_set = PETSC_FALSE; 1306184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 130789b92e6fSPeter Brune snes->gssweeps = 1; 13089b94acceSBarry Smith 13093d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 13103d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 13113d4c4710SBarry Smith 13129b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 131338f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 13149b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 13159b94acceSBarry Smith kctx->version = 2; 13169b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 13179b94acceSBarry Smith this was too large for some test cases */ 131875567043SBarry Smith kctx->rtol_last = 0.0; 13199b94acceSBarry Smith kctx->rtol_max = .9; 13209b94acceSBarry Smith kctx->gamma = 1.0; 132162d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 132271f87433Sdalcinl kctx->alpha2 = kctx->alpha; 13239b94acceSBarry Smith kctx->threshold = .1; 132475567043SBarry Smith kctx->lresid_last = 0.0; 132575567043SBarry Smith kctx->norm_last = 0.0; 13269b94acceSBarry Smith 13279b94acceSBarry Smith *outsnes = snes; 13283a40ed3dSBarry Smith PetscFunctionReturn(0); 13299b94acceSBarry Smith } 13309b94acceSBarry Smith 13314a2ae208SSatish Balay #undef __FUNCT__ 13324a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 13339b94acceSBarry Smith /*@C 13349b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 13359b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 13369b94acceSBarry Smith equations. 13379b94acceSBarry Smith 13383f9fe445SBarry Smith Logically Collective on SNES 1339fee21e36SBarry Smith 1340c7afd0dbSLois Curfman McInnes Input Parameters: 1341c7afd0dbSLois Curfman McInnes + snes - the SNES context 1342c7afd0dbSLois Curfman McInnes . r - vector to store function value 1343de044059SHong Zhang . func - function evaluation routine 1344c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1345c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 13469b94acceSBarry Smith 1347c7afd0dbSLois Curfman McInnes Calling sequence of func: 13488d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1349c7afd0dbSLois Curfman McInnes 1350c586c404SJed Brown + snes - the SNES context 1351c586c404SJed Brown . x - state at which to evaluate residual 1352c586c404SJed Brown . f - vector to put residual 1353c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 13549b94acceSBarry Smith 13559b94acceSBarry Smith Notes: 13569b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 13579b94acceSBarry Smith $ f'(x) x = -f(x), 1358c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 13599b94acceSBarry Smith 136036851e7fSLois Curfman McInnes Level: beginner 136136851e7fSLois Curfman McInnes 13629b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 13639b94acceSBarry Smith 13648b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard() 13659b94acceSBarry Smith @*/ 13667087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 13679b94acceSBarry Smith { 136885385478SLisandro Dalcin PetscErrorCode ierr; 13696cab3a1bSJed Brown DM dm; 13706cab3a1bSJed Brown 13713a40ed3dSBarry Smith PetscFunctionBegin; 13720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1373d2a683ecSLisandro Dalcin if (r) { 1374d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1375d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 137685385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 13776bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 137885385478SLisandro Dalcin snes->vec_func = r; 1379d2a683ecSLisandro Dalcin } 13806cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 13816cab3a1bSJed Brown ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr); 13823a40ed3dSBarry Smith PetscFunctionReturn(0); 13839b94acceSBarry Smith } 13849b94acceSBarry Smith 1385646217ecSPeter Brune 1386646217ecSPeter Brune #undef __FUNCT__ 1387e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction" 1388e4ed7901SPeter Brune /*@C 1389e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1390e4ed7901SPeter Brune function norm at the initialization of the method. In some 1391e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1392e4ed7901SPeter Brune SNESSolve. This function allows one to avoid a redundant call 1393e4ed7901SPeter Brune to SNESComputeFunction in that case. 1394e4ed7901SPeter Brune 1395e4ed7901SPeter Brune Logically Collective on SNES 1396e4ed7901SPeter Brune 1397e4ed7901SPeter Brune Input Parameters: 1398e4ed7901SPeter Brune + snes - the SNES context 1399e4ed7901SPeter Brune - f - vector to store function value 1400e4ed7901SPeter Brune 1401e4ed7901SPeter Brune Notes: 1402e4ed7901SPeter Brune This should not be modified during the solution procedure. 1403e4ed7901SPeter Brune 1404e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1405e4ed7901SPeter Brune 1406e4ed7901SPeter Brune Level: developer 1407e4ed7901SPeter Brune 1408e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function 1409e4ed7901SPeter Brune 1410e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm() 1411e4ed7901SPeter Brune @*/ 1412e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1413e4ed7901SPeter Brune { 1414e4ed7901SPeter Brune PetscErrorCode ierr; 1415e4ed7901SPeter Brune Vec vec_func; 1416e4ed7901SPeter Brune 1417e4ed7901SPeter Brune PetscFunctionBegin; 1418e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1419e4ed7901SPeter Brune PetscValidHeaderSpecific(f,VEC_CLASSID,2); 1420e4ed7901SPeter Brune PetscCheckSameComm(snes,1,f,2); 1421e4ed7901SPeter Brune ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1422e4ed7901SPeter Brune ierr = VecCopy(f, vec_func);CHKERRQ(ierr); 1423217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 1424e4ed7901SPeter Brune PetscFunctionReturn(0); 1425e4ed7901SPeter Brune } 1426e4ed7901SPeter Brune 1427e4ed7901SPeter Brune 1428e4ed7901SPeter Brune #undef __FUNCT__ 1429e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm" 1430e4ed7901SPeter Brune /*@C 1431e4ed7901SPeter Brune SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm 1432e4ed7901SPeter Brune at the initialization of the method. In some instances, the user has precomputed 1433e4ed7901SPeter Brune the function and its norm before calling SNESSolve. This function allows one to 1434e4ed7901SPeter Brune avoid a redundant call to SNESComputeFunction() and VecNorm() in that case. 1435e4ed7901SPeter Brune 1436e4ed7901SPeter Brune Logically Collective on SNES 1437e4ed7901SPeter Brune 1438e4ed7901SPeter Brune Input Parameters: 1439e4ed7901SPeter Brune + snes - the SNES context 1440e4ed7901SPeter Brune - fnorm - the norm of F as set by SNESSetInitialFunction() 1441e4ed7901SPeter Brune 1442e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1443e4ed7901SPeter Brune 1444e4ed7901SPeter Brune Level: developer 1445e4ed7901SPeter Brune 1446e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm 1447e4ed7901SPeter Brune 1448e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction() 1449e4ed7901SPeter Brune @*/ 1450e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm) 1451e4ed7901SPeter Brune { 1452e4ed7901SPeter Brune PetscFunctionBegin; 1453e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1454e4ed7901SPeter Brune snes->norm_init = fnorm; 1455e4ed7901SPeter Brune snes->norm_init_set = PETSC_TRUE; 1456e4ed7901SPeter Brune PetscFunctionReturn(0); 1457e4ed7901SPeter Brune } 1458e4ed7901SPeter Brune 1459e4ed7901SPeter Brune #undef __FUNCT__ 1460534ebe21SPeter Brune #define __FUNCT__ "SNESSetNormType" 1461534ebe21SPeter Brune /*@ 1462534ebe21SPeter Brune SNESSetNormType - Sets the SNESNormType used in covergence and monitoring 1463534ebe21SPeter Brune of the SNES method. 1464534ebe21SPeter Brune 1465534ebe21SPeter Brune Logically Collective on SNES 1466534ebe21SPeter Brune 1467534ebe21SPeter Brune Input Parameters: 1468534ebe21SPeter Brune + snes - the SNES context 1469534ebe21SPeter Brune - normtype - the type of the norm used 1470534ebe21SPeter Brune 1471534ebe21SPeter Brune Notes: 1472534ebe21SPeter Brune Only certain SNES methods support certain SNESNormTypes. Most require evaluation 1473534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1474534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1475534ebe21SPeter Brune (SNESGS) and the like do not require the norm of the function to be computed, and therfore 1476534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1477534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1478534ebe21SPeter Brune their solution. 1479534ebe21SPeter Brune 1480534ebe21SPeter Brune Level: developer 1481534ebe21SPeter Brune 1482534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1483534ebe21SPeter Brune 1484534ebe21SPeter Brune .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType 1485534ebe21SPeter Brune @*/ 1486534ebe21SPeter Brune PetscErrorCode SNESSetNormType(SNES snes, SNESNormType normtype) 1487534ebe21SPeter Brune { 1488534ebe21SPeter Brune PetscFunctionBegin; 1489534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1490534ebe21SPeter Brune snes->normtype = normtype; 1491534ebe21SPeter Brune PetscFunctionReturn(0); 1492534ebe21SPeter Brune } 1493534ebe21SPeter Brune 1494534ebe21SPeter Brune 1495534ebe21SPeter Brune #undef __FUNCT__ 1496534ebe21SPeter Brune #define __FUNCT__ "SNESGetNormType" 1497534ebe21SPeter Brune /*@ 1498534ebe21SPeter Brune SNESGetNormType - Gets the SNESNormType used in covergence and monitoring 1499534ebe21SPeter Brune of the SNES method. 1500534ebe21SPeter Brune 1501534ebe21SPeter Brune Logically Collective on SNES 1502534ebe21SPeter Brune 1503534ebe21SPeter Brune Input Parameters: 1504534ebe21SPeter Brune + snes - the SNES context 1505534ebe21SPeter Brune - normtype - the type of the norm used 1506534ebe21SPeter Brune 1507534ebe21SPeter Brune Level: advanced 1508534ebe21SPeter Brune 1509534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1510534ebe21SPeter Brune 1511534ebe21SPeter Brune .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType 1512534ebe21SPeter Brune @*/ 1513534ebe21SPeter Brune PetscErrorCode SNESGetNormType(SNES snes, SNESNormType *normtype) 1514534ebe21SPeter Brune { 1515534ebe21SPeter Brune PetscFunctionBegin; 1516534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1517534ebe21SPeter Brune *normtype = snes->normtype; 1518534ebe21SPeter Brune PetscFunctionReturn(0); 1519534ebe21SPeter Brune } 1520534ebe21SPeter Brune 1521534ebe21SPeter Brune #undef __FUNCT__ 1522646217ecSPeter Brune #define __FUNCT__ "SNESSetGS" 1523c79ef259SPeter Brune /*@C 1524c79ef259SPeter Brune SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for 1525c79ef259SPeter Brune use with composed nonlinear solvers. 1526c79ef259SPeter Brune 1527c79ef259SPeter Brune Input Parameters: 1528c79ef259SPeter Brune + snes - the SNES context 1529c79ef259SPeter Brune . gsfunc - function evaluation routine 1530c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 1531c79ef259SPeter Brune smoother evaluation routine (may be PETSC_NULL) 1532c79ef259SPeter Brune 1533c79ef259SPeter Brune Calling sequence of func: 1534c79ef259SPeter Brune $ func (SNES snes,Vec x,Vec b,void *ctx); 1535c79ef259SPeter Brune 1536c79ef259SPeter Brune + X - solution vector 1537c79ef259SPeter Brune . B - RHS vector 1538d28543b3SPeter Brune - ctx - optional user-defined Gauss-Seidel context 1539c79ef259SPeter Brune 1540c79ef259SPeter Brune Notes: 1541c79ef259SPeter Brune The GS routines are used by the composed nonlinear solver to generate 1542c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1543c79ef259SPeter Brune 1544d28543b3SPeter Brune Level: intermediate 1545c79ef259SPeter Brune 1546d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1547c79ef259SPeter Brune 1548c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS() 1549c79ef259SPeter Brune @*/ 15506cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx) 15516cab3a1bSJed Brown { 15526cab3a1bSJed Brown PetscErrorCode ierr; 15536cab3a1bSJed Brown DM dm; 15546cab3a1bSJed Brown 1555646217ecSPeter Brune PetscFunctionBegin; 15566cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15576cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 15586cab3a1bSJed Brown ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr); 1559646217ecSPeter Brune PetscFunctionReturn(0); 1560646217ecSPeter Brune } 1561646217ecSPeter Brune 1562d25893d9SBarry Smith #undef __FUNCT__ 156389b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps" 156489b92e6fSPeter Brune /*@ 156589b92e6fSPeter Brune SNESSetGSSweeps - Sets the number of sweeps of GS to use. 156689b92e6fSPeter Brune 156789b92e6fSPeter Brune Input Parameters: 156889b92e6fSPeter Brune + snes - the SNES context 156989b92e6fSPeter Brune - sweeps - the number of sweeps of GS to perform. 157089b92e6fSPeter Brune 157189b92e6fSPeter Brune Level: intermediate 157289b92e6fSPeter Brune 157389b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 157489b92e6fSPeter Brune 157589b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps() 157689b92e6fSPeter Brune @*/ 157789b92e6fSPeter Brune 157889b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) { 157989b92e6fSPeter Brune PetscFunctionBegin; 158089b92e6fSPeter Brune snes->gssweeps = sweeps; 158189b92e6fSPeter Brune PetscFunctionReturn(0); 158289b92e6fSPeter Brune } 158389b92e6fSPeter Brune 158489b92e6fSPeter Brune 158589b92e6fSPeter Brune #undef __FUNCT__ 158689b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps" 158789b92e6fSPeter Brune /*@ 158889b92e6fSPeter Brune SNESGetGSSweeps - Gets the number of sweeps GS will use. 158989b92e6fSPeter Brune 159089b92e6fSPeter Brune Input Parameters: 159189b92e6fSPeter Brune . snes - the SNES context 159289b92e6fSPeter Brune 159389b92e6fSPeter Brune Output Parameters: 159489b92e6fSPeter Brune . sweeps - the number of sweeps of GS to perform. 159589b92e6fSPeter Brune 159689b92e6fSPeter Brune Level: intermediate 159789b92e6fSPeter Brune 159889b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 159989b92e6fSPeter Brune 160089b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps() 160189b92e6fSPeter Brune @*/ 160289b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) { 160389b92e6fSPeter Brune PetscFunctionBegin; 160489b92e6fSPeter Brune *sweeps = snes->gssweeps; 160589b92e6fSPeter Brune PetscFunctionReturn(0); 160689b92e6fSPeter Brune } 160789b92e6fSPeter Brune 160889b92e6fSPeter Brune #undef __FUNCT__ 16098b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 16108b0a5094SBarry Smith PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 16118b0a5094SBarry Smith { 16128b0a5094SBarry Smith PetscErrorCode ierr; 16136cab3a1bSJed Brown void *functx,*jacctx; 16146cab3a1bSJed Brown 16158b0a5094SBarry Smith PetscFunctionBegin; 16166cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 16176cab3a1bSJed Brown ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr); 16188b0a5094SBarry Smith /* A(x)*x - b(x) */ 16196cab3a1bSJed Brown ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr); 16206cab3a1bSJed Brown ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr); 16218b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 16228b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 16238b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 16248b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 16258b0a5094SBarry Smith PetscFunctionReturn(0); 16268b0a5094SBarry Smith } 16278b0a5094SBarry Smith 16288b0a5094SBarry Smith #undef __FUNCT__ 16298b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 16308b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 16318b0a5094SBarry Smith { 16328b0a5094SBarry Smith PetscFunctionBegin; 16338b0a5094SBarry Smith *flag = snes->matstruct; 16348b0a5094SBarry Smith PetscFunctionReturn(0); 16358b0a5094SBarry Smith } 16368b0a5094SBarry Smith 16378b0a5094SBarry Smith #undef __FUNCT__ 16388b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 16398b0a5094SBarry Smith /*@C 16400d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 16418b0a5094SBarry Smith 16428b0a5094SBarry Smith Logically Collective on SNES 16438b0a5094SBarry Smith 16448b0a5094SBarry Smith Input Parameters: 16458b0a5094SBarry Smith + snes - the SNES context 16468b0a5094SBarry Smith . r - vector to store function value 16478b0a5094SBarry Smith . func - function evaluation routine 16488b0a5094SBarry 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) 16498b0a5094SBarry Smith . mat - matrix to store A 16508b0a5094SBarry Smith . mfunc - function to compute matrix value 16518b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 16528b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 16538b0a5094SBarry Smith 16548b0a5094SBarry Smith Calling sequence of func: 16558b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 16568b0a5094SBarry Smith 16578b0a5094SBarry Smith + f - function vector 16588b0a5094SBarry Smith - ctx - optional user-defined function context 16598b0a5094SBarry Smith 16608b0a5094SBarry Smith Calling sequence of mfunc: 16618b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 16628b0a5094SBarry Smith 16638b0a5094SBarry Smith + x - input vector 16648b0a5094SBarry 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(), 16658b0a5094SBarry Smith normally just pass mat in this location 16668b0a5094SBarry Smith . mat - form A(x) matrix 16678b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 16688b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 16698b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 16708b0a5094SBarry Smith 16718b0a5094SBarry Smith Notes: 16728b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 16738b0a5094SBarry Smith 16748b0a5094SBarry 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} 16758b0a5094SBarry 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. 16768b0a5094SBarry Smith 16778b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 16788b0a5094SBarry Smith 16790d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 16800d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 16818b0a5094SBarry Smith 16828b0a5094SBarry 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 16838b0a5094SBarry 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 16848b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 16858b0a5094SBarry Smith 16868b0a5094SBarry Smith Level: beginner 16878b0a5094SBarry Smith 16888b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 16898b0a5094SBarry Smith 16900d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard() 16918b0a5094SBarry Smith @*/ 16928b0a5094SBarry 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) 16938b0a5094SBarry Smith { 16948b0a5094SBarry Smith PetscErrorCode ierr; 16958b0a5094SBarry Smith PetscFunctionBegin; 16968b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16978b0a5094SBarry Smith snes->ops->computepfunction = func; 16988b0a5094SBarry Smith snes->ops->computepjacobian = mfunc; 16998b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 17008b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 17018b0a5094SBarry Smith PetscFunctionReturn(0); 17028b0a5094SBarry Smith } 17038b0a5094SBarry Smith 17048b0a5094SBarry Smith #undef __FUNCT__ 1705d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1706d25893d9SBarry Smith /*@C 1707d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1708d25893d9SBarry Smith 1709d25893d9SBarry Smith Logically Collective on SNES 1710d25893d9SBarry Smith 1711d25893d9SBarry Smith Input Parameters: 1712d25893d9SBarry Smith + snes - the SNES context 1713d25893d9SBarry Smith . func - function evaluation routine 1714d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1715d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1716d25893d9SBarry Smith 1717d25893d9SBarry Smith Calling sequence of func: 1718d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1719d25893d9SBarry Smith 1720d25893d9SBarry Smith . f - function vector 1721d25893d9SBarry Smith - ctx - optional user-defined function context 1722d25893d9SBarry Smith 1723d25893d9SBarry Smith Level: intermediate 1724d25893d9SBarry Smith 1725d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1726d25893d9SBarry Smith 1727d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1728d25893d9SBarry Smith @*/ 1729d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1730d25893d9SBarry Smith { 1731d25893d9SBarry Smith PetscFunctionBegin; 1732d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1733d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1734d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1735d25893d9SBarry Smith PetscFunctionReturn(0); 1736d25893d9SBarry Smith } 1737d25893d9SBarry Smith 17383ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 17393ab0aad5SBarry Smith #undef __FUNCT__ 17401096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 17411096aae1SMatthew Knepley /*@C 17421096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 17431096aae1SMatthew Knepley it assumes a zero right hand side. 17441096aae1SMatthew Knepley 17453f9fe445SBarry Smith Logically Collective on SNES 17461096aae1SMatthew Knepley 17471096aae1SMatthew Knepley Input Parameter: 17481096aae1SMatthew Knepley . snes - the SNES context 17491096aae1SMatthew Knepley 17501096aae1SMatthew Knepley Output Parameter: 1751bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 17521096aae1SMatthew Knepley 17531096aae1SMatthew Knepley Level: intermediate 17541096aae1SMatthew Knepley 17551096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 17561096aae1SMatthew Knepley 175785385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 17581096aae1SMatthew Knepley @*/ 17597087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 17601096aae1SMatthew Knepley { 17611096aae1SMatthew Knepley PetscFunctionBegin; 17620700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 17631096aae1SMatthew Knepley PetscValidPointer(rhs,2); 176485385478SLisandro Dalcin *rhs = snes->vec_rhs; 17651096aae1SMatthew Knepley PetscFunctionReturn(0); 17661096aae1SMatthew Knepley } 17671096aae1SMatthew Knepley 17681096aae1SMatthew Knepley #undef __FUNCT__ 17694a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 17709b94acceSBarry Smith /*@ 177136851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 17729b94acceSBarry Smith SNESSetFunction(). 17739b94acceSBarry Smith 1774c7afd0dbSLois Curfman McInnes Collective on SNES 1775c7afd0dbSLois Curfman McInnes 17769b94acceSBarry Smith Input Parameters: 1777c7afd0dbSLois Curfman McInnes + snes - the SNES context 1778c7afd0dbSLois Curfman McInnes - x - input vector 17799b94acceSBarry Smith 17809b94acceSBarry Smith Output Parameter: 17813638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 17829b94acceSBarry Smith 17831bffabb2SLois Curfman McInnes Notes: 178436851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 178536851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 178636851e7fSLois Curfman McInnes themselves. 178736851e7fSLois Curfman McInnes 178836851e7fSLois Curfman McInnes Level: developer 178936851e7fSLois Curfman McInnes 17909b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 17919b94acceSBarry Smith 1792a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 17939b94acceSBarry Smith @*/ 17947087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 17959b94acceSBarry Smith { 1796dfbe8321SBarry Smith PetscErrorCode ierr; 17976cab3a1bSJed Brown DM dm; 17986cab3a1bSJed Brown SNESDM sdm; 17999b94acceSBarry Smith 18003a40ed3dSBarry Smith PetscFunctionBegin; 18010700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 18020700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 18030700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1804c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1805c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 18064ec14c9cSBarry Smith VecValidValues(x,2,PETSC_TRUE); 1807184914b5SBarry Smith 18086cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18096cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 1810d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 18116cab3a1bSJed Brown if (sdm->computefunction) { 1812d64ed03dSBarry Smith PetscStackPush("SNES user function"); 18136cab3a1bSJed Brown ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 1814d64ed03dSBarry Smith PetscStackPop; 181573250ac0SBarry Smith } else if (snes->dm) { 1816644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1817c90fad12SPeter Brune } else if (snes->vec_rhs) { 1818c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1819644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 182085385478SLisandro Dalcin if (snes->vec_rhs) { 182185385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 18223ab0aad5SBarry Smith } 1823ae3c334cSLois Curfman McInnes snes->nfuncs++; 1824d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 18254ec14c9cSBarry Smith VecValidValues(y,3,PETSC_FALSE); 18263a40ed3dSBarry Smith PetscFunctionReturn(0); 18279b94acceSBarry Smith } 18289b94acceSBarry Smith 18294a2ae208SSatish Balay #undef __FUNCT__ 1830646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1831c79ef259SPeter Brune /*@ 1832c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1833c79ef259SPeter Brune SNESSetGS(). 1834c79ef259SPeter Brune 1835c79ef259SPeter Brune Collective on SNES 1836c79ef259SPeter Brune 1837c79ef259SPeter Brune Input Parameters: 1838c79ef259SPeter Brune + snes - the SNES context 1839c79ef259SPeter Brune . x - input vector 1840c79ef259SPeter Brune - b - rhs vector 1841c79ef259SPeter Brune 1842c79ef259SPeter Brune Output Parameter: 1843c79ef259SPeter Brune . x - new solution vector 1844c79ef259SPeter Brune 1845c79ef259SPeter Brune Notes: 1846c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1847c79ef259SPeter Brune implementations, so most users would not generally call this routine 1848c79ef259SPeter Brune themselves. 1849c79ef259SPeter Brune 1850c79ef259SPeter Brune Level: developer 1851c79ef259SPeter Brune 1852c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1853c79ef259SPeter Brune 1854c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1855c79ef259SPeter Brune @*/ 1856646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1857646217ecSPeter Brune { 1858646217ecSPeter Brune PetscErrorCode ierr; 185989b92e6fSPeter Brune PetscInt i; 18606cab3a1bSJed Brown DM dm; 18616cab3a1bSJed Brown SNESDM sdm; 1862646217ecSPeter Brune 1863646217ecSPeter Brune PetscFunctionBegin; 1864646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1865646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1866646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1867646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 1868646217ecSPeter Brune if(b) PetscCheckSameComm(snes,1,b,3); 18694ec14c9cSBarry Smith if (b) VecValidValues(b,2,PETSC_TRUE); 1870701cf23dSPeter Brune ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 18716cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18726cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 18736cab3a1bSJed Brown if (sdm->computegs) { 187489b92e6fSPeter Brune for (i = 0; i < snes->gssweeps; i++) { 1875646217ecSPeter Brune PetscStackPush("SNES user GS"); 18766cab3a1bSJed Brown ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 1877646217ecSPeter Brune PetscStackPop; 187889b92e6fSPeter Brune } 1879646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 1880701cf23dSPeter Brune ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 18814ec14c9cSBarry Smith VecValidValues(x,3,PETSC_FALSE); 1882646217ecSPeter Brune PetscFunctionReturn(0); 1883646217ecSPeter Brune } 1884646217ecSPeter Brune 1885646217ecSPeter Brune 1886646217ecSPeter Brune #undef __FUNCT__ 18874a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 188862fef451SLois Curfman McInnes /*@ 188962fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 189062fef451SLois Curfman McInnes set with SNESSetJacobian(). 189162fef451SLois Curfman McInnes 1892c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1893c7afd0dbSLois Curfman McInnes 189462fef451SLois Curfman McInnes Input Parameters: 1895c7afd0dbSLois Curfman McInnes + snes - the SNES context 1896c7afd0dbSLois Curfman McInnes - x - input vector 189762fef451SLois Curfman McInnes 189862fef451SLois Curfman McInnes Output Parameters: 1899c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 190062fef451SLois Curfman McInnes . B - optional preconditioning matrix 19012b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1902fee21e36SBarry Smith 1903e35cf81dSBarry Smith Options Database Keys: 1904e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1905693365a8SJed Brown . -snes_lag_jacobian <lag> 1906693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1907693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1908693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 19094c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1910c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 1911c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 1912c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 1913c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 1914c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 19154c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 1916c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 1917c01495d3SJed Brown 1918e35cf81dSBarry Smith 191962fef451SLois Curfman McInnes Notes: 192062fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 192162fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 192262fef451SLois Curfman McInnes 192394b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1924dc5a77f8SLois Curfman McInnes flag parameter. 192562fef451SLois Curfman McInnes 192636851e7fSLois Curfman McInnes Level: developer 192736851e7fSLois Curfman McInnes 192862fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 192962fef451SLois Curfman McInnes 1930e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 193162fef451SLois Curfman McInnes @*/ 19327087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 19339b94acceSBarry Smith { 1934dfbe8321SBarry Smith PetscErrorCode ierr; 1935ace3abfcSBarry Smith PetscBool flag; 19366cab3a1bSJed Brown DM dm; 19376cab3a1bSJed Brown SNESDM sdm; 19383a40ed3dSBarry Smith 19393a40ed3dSBarry Smith PetscFunctionBegin; 19400700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 19410700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 19424482741eSBarry Smith PetscValidPointer(flg,5); 1943c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 19444ec14c9cSBarry Smith VecValidValues(X,2,PETSC_TRUE); 19456cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 19466cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 19476cab3a1bSJed Brown if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 1948ebd3b9afSBarry Smith 1949ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1950ebd3b9afSBarry Smith 1951fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 1952fe3ffe1eSBarry Smith snes->lagjacobian = -1; 1953fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1954fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 1955e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1956e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1957251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1958ebd3b9afSBarry Smith if (flag) { 1959ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1960ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1961ebd3b9afSBarry Smith } 1962e35cf81dSBarry Smith PetscFunctionReturn(0); 1963e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1964e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1965e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1966251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1967ebd3b9afSBarry Smith if (flag) { 1968ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1969ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1970ebd3b9afSBarry Smith } 1971e35cf81dSBarry Smith PetscFunctionReturn(0); 1972e35cf81dSBarry Smith } 1973e35cf81dSBarry Smith 1974c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 1975e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1976d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 19776cab3a1bSJed Brown ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr); 1978d64ed03dSBarry Smith PetscStackPop; 1979d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1980a8054027SBarry Smith 19813b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 19823b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 19833b4f5425SBarry Smith snes->lagpreconditioner = -1; 19843b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 1985a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1986a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 1987a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 1988a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1989a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 1990a8054027SBarry Smith } 1991a8054027SBarry Smith 19926d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 19930700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 19940700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 1995693365a8SJed Brown { 1996693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 1997693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 1998693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 1999693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 2000693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 2001693365a8SJed Brown if (flag || flag_draw || flag_contour) { 2002693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 2003693365a8SJed Brown MatStructure mstruct; 2004693365a8SJed Brown PetscViewer vdraw,vstdout; 20056b3a5b13SJed Brown PetscBool flg; 2006693365a8SJed Brown if (flag_operator) { 2007693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 2008693365a8SJed Brown Bexp = Bexp_mine; 2009693365a8SJed Brown } else { 2010693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 2011251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 2012693365a8SJed Brown if (flg) Bexp = *B; 2013693365a8SJed Brown else { 2014693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 2015693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 2016693365a8SJed Brown Bexp = Bexp_mine; 2017693365a8SJed Brown } 2018693365a8SJed Brown } 2019693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 2020693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 2021693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 2022693365a8SJed Brown if (flag_draw || flag_contour) { 2023693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2024693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 2025693365a8SJed Brown } else vdraw = PETSC_NULL; 2026693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 2027693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 2028693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 2029693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 2030693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2031693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 2032693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2033693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 2034693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2035693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 2036693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2037693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 2038693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2039693365a8SJed Brown } 2040693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2041693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2042693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 2043693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 2044693365a8SJed Brown } 2045693365a8SJed Brown } 20464c30e9fbSJed Brown { 20476719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 20486719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 20494c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 20506719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 20514c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 20524c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 20536719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 20546719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 20556719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 20566719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 20574c30e9fbSJed Brown Mat Bfd; 20584c30e9fbSJed Brown MatStructure mstruct; 20594c30e9fbSJed Brown PetscViewer vdraw,vstdout; 20604c30e9fbSJed Brown ISColoring iscoloring; 20614c30e9fbSJed Brown MatFDColoring matfdcoloring; 20624c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 20634c30e9fbSJed Brown void *funcctx; 20646719d8e4SJed Brown PetscReal norm1,norm2,normmax; 20654c30e9fbSJed Brown 20664c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 20674c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 20684c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 20694c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 20704c30e9fbSJed Brown 20714c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 20724c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 20734c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 20744c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 20754c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 20764c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 20774c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 20784c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 20794c30e9fbSJed Brown 20804c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 20814c30e9fbSJed Brown if (flag_draw || flag_contour) { 20824c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 20834c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 20844c30e9fbSJed Brown } else vdraw = PETSC_NULL; 20854c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 20866719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 20874c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 20884c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 20896719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 20904c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 20914c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 20924c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 20936719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 20944c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 20956719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 20966719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 20974c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 20984c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 20994c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 21004c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 21014c30e9fbSJed Brown } 21024c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 21036719d8e4SJed Brown 21046719d8e4SJed Brown if (flag_threshold) { 21056719d8e4SJed Brown PetscInt bs,rstart,rend,i; 21066719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 21076719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 21086719d8e4SJed Brown for (i=rstart; i<rend; i++) { 21096719d8e4SJed Brown const PetscScalar *ba,*ca; 21106719d8e4SJed Brown const PetscInt *bj,*cj; 21116719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 21126719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 21136719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 21146719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 21156719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 21166719d8e4SJed Brown for (j=0; j<bn; j++) { 21176719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 21186719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 21196719d8e4SJed Brown maxentrycol = bj[j]; 21206719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 21216719d8e4SJed Brown } 21226719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 21236719d8e4SJed Brown maxdiffcol = bj[j]; 21246719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 21256719d8e4SJed Brown } 21266719d8e4SJed Brown if (rdiff > maxrdiff) { 21276719d8e4SJed Brown maxrdiffcol = bj[j]; 21286719d8e4SJed Brown maxrdiff = rdiff; 21296719d8e4SJed Brown } 21306719d8e4SJed Brown } 21316719d8e4SJed Brown if (maxrdiff > 1) { 21326719d8e4SJed 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); 21336719d8e4SJed Brown for (j=0; j<bn; j++) { 21346719d8e4SJed Brown PetscReal rdiff; 21356719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 21366719d8e4SJed Brown if (rdiff > 1) { 21376719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 21386719d8e4SJed Brown } 21396719d8e4SJed Brown } 21406719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 21416719d8e4SJed Brown } 21426719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 21436719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 21446719d8e4SJed Brown } 21456719d8e4SJed Brown } 21464c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 21474c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 21484c30e9fbSJed Brown } 21494c30e9fbSJed Brown } 21503a40ed3dSBarry Smith PetscFunctionReturn(0); 21519b94acceSBarry Smith } 21529b94acceSBarry Smith 21534a2ae208SSatish Balay #undef __FUNCT__ 21544a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 21559b94acceSBarry Smith /*@C 21569b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2157044dda88SLois Curfman McInnes location to store the matrix. 21589b94acceSBarry Smith 21593f9fe445SBarry Smith Logically Collective on SNES and Mat 2160c7afd0dbSLois Curfman McInnes 21619b94acceSBarry Smith Input Parameters: 2162c7afd0dbSLois Curfman McInnes + snes - the SNES context 21639b94acceSBarry Smith . A - Jacobian matrix 21649b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 2165efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 2166c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 2167efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 21689b94acceSBarry Smith 21699b94acceSBarry Smith Calling sequence of func: 21708d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 21719b94acceSBarry Smith 2172c7afd0dbSLois Curfman McInnes + x - input vector 21739b94acceSBarry Smith . A - Jacobian matrix 21749b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 2175ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 21762b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 2177c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 21789b94acceSBarry Smith 21799b94acceSBarry Smith Notes: 218094b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 21812cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 2182ac21db08SLois Curfman McInnes 2183ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 21849b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 21859b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 21869b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 21879b94acceSBarry Smith throughout the global iterations. 21889b94acceSBarry Smith 218916913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 219016913363SBarry Smith each matrix. 219116913363SBarry Smith 2192a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 2193a8a26c1eSJed Brown must be a MatFDColoring. 2194a8a26c1eSJed Brown 2195c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2196c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2197c3cc8fd1SJed Brown 219836851e7fSLois Curfman McInnes Level: beginner 219936851e7fSLois Curfman McInnes 22009b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 22019b94acceSBarry Smith 22023ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 22039b94acceSBarry Smith @*/ 22047087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 22059b94acceSBarry Smith { 2206dfbe8321SBarry Smith PetscErrorCode ierr; 22076cab3a1bSJed Brown DM dm; 22083a7fca6bSBarry Smith 22093a40ed3dSBarry Smith PetscFunctionBegin; 22100700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 22110700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 22120700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 2213c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 221406975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 22156cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 22166cab3a1bSJed Brown ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr); 22173a7fca6bSBarry Smith if (A) { 22187dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 22196bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 22209b94acceSBarry Smith snes->jacobian = A; 22213a7fca6bSBarry Smith } 22223a7fca6bSBarry Smith if (B) { 22237dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 22246bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 22259b94acceSBarry Smith snes->jacobian_pre = B; 22263a7fca6bSBarry Smith } 22273a40ed3dSBarry Smith PetscFunctionReturn(0); 22289b94acceSBarry Smith } 222962fef451SLois Curfman McInnes 22304a2ae208SSatish Balay #undef __FUNCT__ 22314a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 2232c2aafc4cSSatish Balay /*@C 2233b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2234b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2235b4fd4287SBarry Smith 2236c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2237c7afd0dbSLois Curfman McInnes 2238b4fd4287SBarry Smith Input Parameter: 2239b4fd4287SBarry Smith . snes - the nonlinear solver context 2240b4fd4287SBarry Smith 2241b4fd4287SBarry Smith Output Parameters: 2242c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 2243b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 224470e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 224570e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 2246fee21e36SBarry Smith 224736851e7fSLois Curfman McInnes Level: advanced 224836851e7fSLois Curfman McInnes 2249b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 2250b4fd4287SBarry Smith @*/ 22517087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 2252b4fd4287SBarry Smith { 22536cab3a1bSJed Brown PetscErrorCode ierr; 22546cab3a1bSJed Brown DM dm; 22556cab3a1bSJed Brown SNESDM sdm; 22566cab3a1bSJed Brown 22573a40ed3dSBarry Smith PetscFunctionBegin; 22580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2259b4fd4287SBarry Smith if (A) *A = snes->jacobian; 2260b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 22616cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 22626cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 22636cab3a1bSJed Brown if (func) *func = sdm->computejacobian; 22646cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 22653a40ed3dSBarry Smith PetscFunctionReturn(0); 2266b4fd4287SBarry Smith } 2267b4fd4287SBarry Smith 22689b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 22699b94acceSBarry Smith 22704a2ae208SSatish Balay #undef __FUNCT__ 22714a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 22729b94acceSBarry Smith /*@ 22739b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2274272ac6f2SLois Curfman McInnes of a nonlinear solver. 22759b94acceSBarry Smith 2276fee21e36SBarry Smith Collective on SNES 2277fee21e36SBarry Smith 2278c7afd0dbSLois Curfman McInnes Input Parameters: 227970e92668SMatthew Knepley . snes - the SNES context 2280c7afd0dbSLois Curfman McInnes 2281272ac6f2SLois Curfman McInnes Notes: 2282272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2283272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2284272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2285272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2286272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2287272ac6f2SLois Curfman McInnes 228836851e7fSLois Curfman McInnes Level: advanced 228936851e7fSLois Curfman McInnes 22909b94acceSBarry Smith .keywords: SNES, nonlinear, setup 22919b94acceSBarry Smith 22929b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 22939b94acceSBarry Smith @*/ 22947087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 22959b94acceSBarry Smith { 2296dfbe8321SBarry Smith PetscErrorCode ierr; 22976cab3a1bSJed Brown DM dm; 22986cab3a1bSJed Brown SNESDM sdm; 22996e2a1849SPeter Brune SNESLineSearch linesearch; 23006e2a1849SPeter Brune SNESLineSearch pclinesearch; 23016e2a1849SPeter Brune void *lsprectx,*lspostctx; 23026e2a1849SPeter Brune SNESLineSearchPreCheckFunc lsprefunc; 23036e2a1849SPeter Brune SNESLineSearchPostCheckFunc lspostfunc; 23046e2a1849SPeter Brune PetscErrorCode (*func)(SNES,Vec,Vec,void*); 23056e2a1849SPeter Brune Vec f,fpc; 23066e2a1849SPeter Brune void *funcctx; 23076e2a1849SPeter Brune PetscErrorCode (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 23086e2a1849SPeter Brune void *jacctx; 23096e2a1849SPeter Brune Mat A,B; 23103a40ed3dSBarry Smith 23113a40ed3dSBarry Smith PetscFunctionBegin; 23120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23134dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 23149b94acceSBarry Smith 23157adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 231685385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 231785385478SLisandro Dalcin } 231885385478SLisandro Dalcin 2319a63bb30eSJed Brown ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 232017186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 232158c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 232258c9b817SLisandro Dalcin 232358c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 232458c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 232558c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 232658c9b817SLisandro Dalcin } 232758c9b817SLisandro Dalcin 23286cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 23296cab3a1bSJed Brown ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */ 23306cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 23316cab3a1bSJed Brown if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc"); 23326cab3a1bSJed Brown if (!snes->vec_func) { 23336cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2334214df951SJed Brown } 2335efd51863SBarry Smith 2336b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 2337b710008aSBarry Smith 2338f1c6b773SPeter Brune if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);} 23399e764e56SPeter Brune 2340d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 2341d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2342d25893d9SBarry Smith } 2343d25893d9SBarry Smith 23446e2a1849SPeter Brune if (snes->pc) { 23456e2a1849SPeter Brune /* copy the DM over */ 23466e2a1849SPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 23476e2a1849SPeter Brune ierr = SNESSetDM(snes->pc,dm);CHKERRQ(ierr); 23486e2a1849SPeter Brune 23496e2a1849SPeter Brune /* copy the legacy SNES context not related to the DM over*/ 23506e2a1849SPeter Brune ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr); 23516e2a1849SPeter Brune ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr); 23526e2a1849SPeter Brune ierr = SNESSetFunction(snes->pc,fpc,func,funcctx);CHKERRQ(ierr); 23536e2a1849SPeter Brune ierr = SNESGetJacobian(snes,&A,&B,&jac,&jacctx);CHKERRQ(ierr); 23546e2a1849SPeter Brune ierr = SNESSetJacobian(snes->pc,A,B,jac,jacctx);CHKERRQ(ierr); 23556e2a1849SPeter Brune ierr = VecDestroy(&fpc);CHKERRQ(ierr); 23566e2a1849SPeter Brune 23576e2a1849SPeter Brune /* copy the function pointers over */ 23586e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr); 23596e2a1849SPeter Brune 23606e2a1849SPeter Brune /* default to 1 iteration */ 23616e2a1849SPeter Brune ierr = SNESSetTolerances(snes->pc, snes->pc->abstol, snes->pc->rtol, snes->pc->stol, 1, snes->pc->max_funcs);CHKERRQ(ierr); 23626e2a1849SPeter Brune ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); 23636e2a1849SPeter Brune ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 23646e2a1849SPeter Brune 23656e2a1849SPeter Brune /* copy the line search context over */ 23666e2a1849SPeter Brune ierr = SNESGetSNESLineSearch(snes,&linesearch);CHKERRQ(ierr); 23676e2a1849SPeter Brune ierr = SNESGetSNESLineSearch(snes->pc,&pclinesearch);CHKERRQ(ierr); 23686e2a1849SPeter Brune ierr = SNESLineSearchGetPreCheck(linesearch,&lsprefunc,&lsprectx);CHKERRQ(ierr); 23696e2a1849SPeter Brune ierr = SNESLineSearchGetPostCheck(linesearch,&lspostfunc,&lspostctx);CHKERRQ(ierr); 23706e2a1849SPeter Brune ierr = SNESLineSearchSetPreCheck(pclinesearch,lsprefunc,lsprectx);CHKERRQ(ierr); 23716e2a1849SPeter Brune ierr = SNESLineSearchSetPostCheck(pclinesearch,lspostfunc,lspostctx);CHKERRQ(ierr); 23726e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr); 23736e2a1849SPeter Brune } 23746e2a1849SPeter Brune 2375410397dcSLisandro Dalcin if (snes->ops->setup) { 2376410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2377410397dcSLisandro Dalcin } 237858c9b817SLisandro Dalcin 23797aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 23803a40ed3dSBarry Smith PetscFunctionReturn(0); 23819b94acceSBarry Smith } 23829b94acceSBarry Smith 23834a2ae208SSatish Balay #undef __FUNCT__ 238437596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 238537596af1SLisandro Dalcin /*@ 238637596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 238737596af1SLisandro Dalcin 238837596af1SLisandro Dalcin Collective on SNES 238937596af1SLisandro Dalcin 239037596af1SLisandro Dalcin Input Parameter: 239137596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 239237596af1SLisandro Dalcin 2393d25893d9SBarry Smith Level: intermediate 2394d25893d9SBarry Smith 2395d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 239637596af1SLisandro Dalcin 239737596af1SLisandro Dalcin .keywords: SNES, destroy 239837596af1SLisandro Dalcin 239937596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 240037596af1SLisandro Dalcin @*/ 240137596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 240237596af1SLisandro Dalcin { 240337596af1SLisandro Dalcin PetscErrorCode ierr; 240437596af1SLisandro Dalcin 240537596af1SLisandro Dalcin PetscFunctionBegin; 240637596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2407d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2408d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2409d25893d9SBarry Smith snes->user = PETSC_NULL; 2410d25893d9SBarry Smith } 24118a23116dSBarry Smith if (snes->pc) { 24128a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 24138a23116dSBarry Smith } 24148a23116dSBarry Smith 241537596af1SLisandro Dalcin if (snes->ops->reset) { 241637596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 241737596af1SLisandro Dalcin } 24189e764e56SPeter Brune if (snes->ksp) { 24199e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 24209e764e56SPeter Brune } 24219e764e56SPeter Brune 24229e764e56SPeter Brune if (snes->linesearch) { 2423f1c6b773SPeter Brune ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 24249e764e56SPeter Brune } 24259e764e56SPeter Brune 24266bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 24276bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 24286bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 24296bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 24306bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 24316bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2432c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2433c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 243437596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 243537596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 243637596af1SLisandro Dalcin PetscFunctionReturn(0); 243737596af1SLisandro Dalcin } 243837596af1SLisandro Dalcin 243937596af1SLisandro Dalcin #undef __FUNCT__ 24404a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 244152baeb72SSatish Balay /*@ 24429b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 24439b94acceSBarry Smith with SNESCreate(). 24449b94acceSBarry Smith 2445c7afd0dbSLois Curfman McInnes Collective on SNES 2446c7afd0dbSLois Curfman McInnes 24479b94acceSBarry Smith Input Parameter: 24489b94acceSBarry Smith . snes - the SNES context 24499b94acceSBarry Smith 245036851e7fSLois Curfman McInnes Level: beginner 245136851e7fSLois Curfman McInnes 24529b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 24539b94acceSBarry Smith 245463a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 24559b94acceSBarry Smith @*/ 24566bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 24579b94acceSBarry Smith { 24586849ba73SBarry Smith PetscErrorCode ierr; 24593a40ed3dSBarry Smith 24603a40ed3dSBarry Smith PetscFunctionBegin; 24616bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 24626bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 24636bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2464d4bb536fSBarry Smith 24656bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 24668a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 24676b8b9a38SLisandro Dalcin 2468be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 24696bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 24706bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 24716d4c513bSLisandro Dalcin 24726bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 24736bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 2474f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 24756b8b9a38SLisandro Dalcin 24766bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 24776bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 24786bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 24796b8b9a38SLisandro Dalcin } 24806bf464f9SBarry Smith if ((*snes)->conv_malloc) { 24816bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 24826bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 248358c9b817SLisandro Dalcin } 24846bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2485a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 24863a40ed3dSBarry Smith PetscFunctionReturn(0); 24879b94acceSBarry Smith } 24889b94acceSBarry Smith 24899b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 24909b94acceSBarry Smith 24914a2ae208SSatish Balay #undef __FUNCT__ 2492a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2493a8054027SBarry Smith /*@ 2494a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2495a8054027SBarry Smith 24963f9fe445SBarry Smith Logically Collective on SNES 2497a8054027SBarry Smith 2498a8054027SBarry Smith Input Parameters: 2499a8054027SBarry Smith + snes - the SNES context 2500a8054027SBarry 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 25013b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2502a8054027SBarry Smith 2503a8054027SBarry Smith Options Database Keys: 2504a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2505a8054027SBarry Smith 2506a8054027SBarry Smith Notes: 2507a8054027SBarry Smith The default is 1 2508a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2509a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2510a8054027SBarry Smith 2511a8054027SBarry Smith Level: intermediate 2512a8054027SBarry Smith 2513a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2514a8054027SBarry Smith 2515e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2516a8054027SBarry Smith 2517a8054027SBarry Smith @*/ 25187087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2519a8054027SBarry Smith { 2520a8054027SBarry Smith PetscFunctionBegin; 25210700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2522e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2523e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2524c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2525a8054027SBarry Smith snes->lagpreconditioner = lag; 2526a8054027SBarry Smith PetscFunctionReturn(0); 2527a8054027SBarry Smith } 2528a8054027SBarry Smith 2529a8054027SBarry Smith #undef __FUNCT__ 2530efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2531efd51863SBarry Smith /*@ 2532efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2533efd51863SBarry Smith 2534efd51863SBarry Smith Logically Collective on SNES 2535efd51863SBarry Smith 2536efd51863SBarry Smith Input Parameters: 2537efd51863SBarry Smith + snes - the SNES context 2538efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2539efd51863SBarry Smith 2540efd51863SBarry Smith Options Database Keys: 2541efd51863SBarry Smith . -snes_grid_sequence <steps> 2542efd51863SBarry Smith 2543efd51863SBarry Smith Level: intermediate 2544efd51863SBarry Smith 2545c0df2a02SJed Brown Notes: 2546c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2547c0df2a02SJed Brown 2548efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2549efd51863SBarry Smith 2550efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2551efd51863SBarry Smith 2552efd51863SBarry Smith @*/ 2553efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2554efd51863SBarry Smith { 2555efd51863SBarry Smith PetscFunctionBegin; 2556efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2557efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2558efd51863SBarry Smith snes->gridsequence = steps; 2559efd51863SBarry Smith PetscFunctionReturn(0); 2560efd51863SBarry Smith } 2561efd51863SBarry Smith 2562efd51863SBarry Smith #undef __FUNCT__ 2563a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2564a8054027SBarry Smith /*@ 2565a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2566a8054027SBarry Smith 25673f9fe445SBarry Smith Not Collective 2568a8054027SBarry Smith 2569a8054027SBarry Smith Input Parameter: 2570a8054027SBarry Smith . snes - the SNES context 2571a8054027SBarry Smith 2572a8054027SBarry Smith Output Parameter: 2573a8054027SBarry 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 25743b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2575a8054027SBarry Smith 2576a8054027SBarry Smith Options Database Keys: 2577a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2578a8054027SBarry Smith 2579a8054027SBarry Smith Notes: 2580a8054027SBarry Smith The default is 1 2581a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2582a8054027SBarry Smith 2583a8054027SBarry Smith Level: intermediate 2584a8054027SBarry Smith 2585a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2586a8054027SBarry Smith 2587a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2588a8054027SBarry Smith 2589a8054027SBarry Smith @*/ 25907087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2591a8054027SBarry Smith { 2592a8054027SBarry Smith PetscFunctionBegin; 25930700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2594a8054027SBarry Smith *lag = snes->lagpreconditioner; 2595a8054027SBarry Smith PetscFunctionReturn(0); 2596a8054027SBarry Smith } 2597a8054027SBarry Smith 2598a8054027SBarry Smith #undef __FUNCT__ 2599e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2600e35cf81dSBarry Smith /*@ 2601e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2602e35cf81dSBarry Smith often the preconditioner is rebuilt. 2603e35cf81dSBarry Smith 26043f9fe445SBarry Smith Logically Collective on SNES 2605e35cf81dSBarry Smith 2606e35cf81dSBarry Smith Input Parameters: 2607e35cf81dSBarry Smith + snes - the SNES context 2608e35cf81dSBarry 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 2609fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2610e35cf81dSBarry Smith 2611e35cf81dSBarry Smith Options Database Keys: 2612e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2613e35cf81dSBarry Smith 2614e35cf81dSBarry Smith Notes: 2615e35cf81dSBarry Smith The default is 1 2616e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2617fe3ffe1eSBarry 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 2618fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2619e35cf81dSBarry Smith 2620e35cf81dSBarry Smith Level: intermediate 2621e35cf81dSBarry Smith 2622e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2623e35cf81dSBarry Smith 2624e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2625e35cf81dSBarry Smith 2626e35cf81dSBarry Smith @*/ 26277087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2628e35cf81dSBarry Smith { 2629e35cf81dSBarry Smith PetscFunctionBegin; 26300700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2631e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2632e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2633c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2634e35cf81dSBarry Smith snes->lagjacobian = lag; 2635e35cf81dSBarry Smith PetscFunctionReturn(0); 2636e35cf81dSBarry Smith } 2637e35cf81dSBarry Smith 2638e35cf81dSBarry Smith #undef __FUNCT__ 2639e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2640e35cf81dSBarry Smith /*@ 2641e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2642e35cf81dSBarry Smith 26433f9fe445SBarry Smith Not Collective 2644e35cf81dSBarry Smith 2645e35cf81dSBarry Smith Input Parameter: 2646e35cf81dSBarry Smith . snes - the SNES context 2647e35cf81dSBarry Smith 2648e35cf81dSBarry Smith Output Parameter: 2649e35cf81dSBarry 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 2650e35cf81dSBarry Smith the Jacobian is built etc. 2651e35cf81dSBarry Smith 2652e35cf81dSBarry Smith Options Database Keys: 2653e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2654e35cf81dSBarry Smith 2655e35cf81dSBarry Smith Notes: 2656e35cf81dSBarry Smith The default is 1 2657e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2658e35cf81dSBarry Smith 2659e35cf81dSBarry Smith Level: intermediate 2660e35cf81dSBarry Smith 2661e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2662e35cf81dSBarry Smith 2663e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2664e35cf81dSBarry Smith 2665e35cf81dSBarry Smith @*/ 26667087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2667e35cf81dSBarry Smith { 2668e35cf81dSBarry Smith PetscFunctionBegin; 26690700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2670e35cf81dSBarry Smith *lag = snes->lagjacobian; 2671e35cf81dSBarry Smith PetscFunctionReturn(0); 2672e35cf81dSBarry Smith } 2673e35cf81dSBarry Smith 2674e35cf81dSBarry Smith #undef __FUNCT__ 26754a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 26769b94acceSBarry Smith /*@ 2677d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 26789b94acceSBarry Smith 26793f9fe445SBarry Smith Logically Collective on SNES 2680c7afd0dbSLois Curfman McInnes 26819b94acceSBarry Smith Input Parameters: 2682c7afd0dbSLois Curfman McInnes + snes - the SNES context 268370441072SBarry Smith . abstol - absolute convergence tolerance 268433174efeSLois Curfman McInnes . rtol - relative convergence tolerance 268533174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 268633174efeSLois Curfman McInnes of the change in the solution between steps 268733174efeSLois Curfman McInnes . maxit - maximum number of iterations 2688c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2689fee21e36SBarry Smith 269033174efeSLois Curfman McInnes Options Database Keys: 269170441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2692c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2693c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2694c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2695c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 26969b94acceSBarry Smith 2697d7a720efSLois Curfman McInnes Notes: 26989b94acceSBarry Smith The default maximum number of iterations is 50. 26999b94acceSBarry Smith The default maximum number of function evaluations is 1000. 27009b94acceSBarry Smith 270136851e7fSLois Curfman McInnes Level: intermediate 270236851e7fSLois Curfman McInnes 270333174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 27049b94acceSBarry Smith 27052492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 27069b94acceSBarry Smith @*/ 27077087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 27089b94acceSBarry Smith { 27093a40ed3dSBarry Smith PetscFunctionBegin; 27100700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2711c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2712c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2713c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2714c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2715c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2716c5eb9154SBarry Smith 2717ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2718ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2719ab54825eSJed Brown snes->abstol = abstol; 2720ab54825eSJed Brown } 2721ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2722ab54825eSJed 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); 2723ab54825eSJed Brown snes->rtol = rtol; 2724ab54825eSJed Brown } 2725ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2726ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2727c60f73f4SPeter Brune snes->stol = stol; 2728ab54825eSJed Brown } 2729ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2730ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2731ab54825eSJed Brown snes->max_its = maxit; 2732ab54825eSJed Brown } 2733ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2734ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2735ab54825eSJed Brown snes->max_funcs = maxf; 2736ab54825eSJed Brown } 273788976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 27383a40ed3dSBarry Smith PetscFunctionReturn(0); 27399b94acceSBarry Smith } 27409b94acceSBarry Smith 27414a2ae208SSatish Balay #undef __FUNCT__ 27424a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 27439b94acceSBarry Smith /*@ 274433174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 274533174efeSLois Curfman McInnes 2746c7afd0dbSLois Curfman McInnes Not Collective 2747c7afd0dbSLois Curfman McInnes 274833174efeSLois Curfman McInnes Input Parameters: 2749c7afd0dbSLois Curfman McInnes + snes - the SNES context 275085385478SLisandro Dalcin . atol - absolute convergence tolerance 275133174efeSLois Curfman McInnes . rtol - relative convergence tolerance 275233174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 275333174efeSLois Curfman McInnes of the change in the solution between steps 275433174efeSLois Curfman McInnes . maxit - maximum number of iterations 2755c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2756fee21e36SBarry Smith 275733174efeSLois Curfman McInnes Notes: 275833174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 275933174efeSLois Curfman McInnes 276036851e7fSLois Curfman McInnes Level: intermediate 276136851e7fSLois Curfman McInnes 276233174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 276333174efeSLois Curfman McInnes 276433174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 276533174efeSLois Curfman McInnes @*/ 27667087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 276733174efeSLois Curfman McInnes { 27683a40ed3dSBarry Smith PetscFunctionBegin; 27690700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 277085385478SLisandro Dalcin if (atol) *atol = snes->abstol; 277133174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 2772c60f73f4SPeter Brune if (stol) *stol = snes->stol; 277333174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 277433174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 27753a40ed3dSBarry Smith PetscFunctionReturn(0); 277633174efeSLois Curfman McInnes } 277733174efeSLois Curfman McInnes 27784a2ae208SSatish Balay #undef __FUNCT__ 27794a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 278033174efeSLois Curfman McInnes /*@ 27819b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 27829b94acceSBarry Smith 27833f9fe445SBarry Smith Logically Collective on SNES 2784fee21e36SBarry Smith 2785c7afd0dbSLois Curfman McInnes Input Parameters: 2786c7afd0dbSLois Curfman McInnes + snes - the SNES context 2787c7afd0dbSLois Curfman McInnes - tol - tolerance 2788c7afd0dbSLois Curfman McInnes 27899b94acceSBarry Smith Options Database Key: 2790c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 27919b94acceSBarry Smith 279236851e7fSLois Curfman McInnes Level: intermediate 279336851e7fSLois Curfman McInnes 27949b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 27959b94acceSBarry Smith 27962492ecdbSBarry Smith .seealso: SNESSetTolerances() 27979b94acceSBarry Smith @*/ 27987087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 27999b94acceSBarry Smith { 28003a40ed3dSBarry Smith PetscFunctionBegin; 28010700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2802c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 28039b94acceSBarry Smith snes->deltatol = tol; 28043a40ed3dSBarry Smith PetscFunctionReturn(0); 28059b94acceSBarry Smith } 28069b94acceSBarry Smith 2807df9fa365SBarry Smith /* 2808df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2809df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2810df9fa365SBarry Smith macros instead of functions 2811df9fa365SBarry Smith */ 28124a2ae208SSatish Balay #undef __FUNCT__ 2813a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 28147087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2815ce1608b8SBarry Smith { 2816dfbe8321SBarry Smith PetscErrorCode ierr; 2817ce1608b8SBarry Smith 2818ce1608b8SBarry Smith PetscFunctionBegin; 28190700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2820a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2821ce1608b8SBarry Smith PetscFunctionReturn(0); 2822ce1608b8SBarry Smith } 2823ce1608b8SBarry Smith 28244a2ae208SSatish Balay #undef __FUNCT__ 2825a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 28267087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2827df9fa365SBarry Smith { 2828dfbe8321SBarry Smith PetscErrorCode ierr; 2829df9fa365SBarry Smith 2830df9fa365SBarry Smith PetscFunctionBegin; 2831a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2832df9fa365SBarry Smith PetscFunctionReturn(0); 2833df9fa365SBarry Smith } 2834df9fa365SBarry Smith 28354a2ae208SSatish Balay #undef __FUNCT__ 2836a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 28376bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2838df9fa365SBarry Smith { 2839dfbe8321SBarry Smith PetscErrorCode ierr; 2840df9fa365SBarry Smith 2841df9fa365SBarry Smith PetscFunctionBegin; 2842a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2843df9fa365SBarry Smith PetscFunctionReturn(0); 2844df9fa365SBarry Smith } 2845df9fa365SBarry Smith 28467087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2847b271bb04SBarry Smith #undef __FUNCT__ 2848b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 28497087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2850b271bb04SBarry Smith { 2851b271bb04SBarry Smith PetscDrawLG lg; 2852b271bb04SBarry Smith PetscErrorCode ierr; 2853b271bb04SBarry Smith PetscReal x,y,per; 2854b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2855b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2856b271bb04SBarry Smith PetscDraw draw; 2857b271bb04SBarry Smith PetscFunctionBegin; 2858b271bb04SBarry Smith if (!monctx) { 2859b271bb04SBarry Smith MPI_Comm comm; 2860b271bb04SBarry Smith 2861b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2862b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2863b271bb04SBarry Smith } 2864b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2865b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2866b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2867b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2868b271bb04SBarry Smith x = (PetscReal) n; 2869b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2870b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2871b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2872b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2873b271bb04SBarry Smith } 2874b271bb04SBarry Smith 2875b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2876b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2877b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2878b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2879b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2880b271bb04SBarry Smith x = (PetscReal) n; 2881b271bb04SBarry Smith y = 100.0*per; 2882b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2883b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2884b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2885b271bb04SBarry Smith } 2886b271bb04SBarry Smith 2887b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2888b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2889b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2890b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2891b271bb04SBarry Smith x = (PetscReal) n; 2892b271bb04SBarry Smith y = (prev - rnorm)/prev; 2893b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2894b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2895b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2896b271bb04SBarry Smith } 2897b271bb04SBarry Smith 2898b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2899b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2900b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2901b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2902b271bb04SBarry Smith x = (PetscReal) n; 2903b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2904b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2905b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2906b271bb04SBarry Smith } 2907b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2908b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2909b271bb04SBarry Smith } 2910b271bb04SBarry Smith prev = rnorm; 2911b271bb04SBarry Smith PetscFunctionReturn(0); 2912b271bb04SBarry Smith } 2913b271bb04SBarry Smith 2914b271bb04SBarry Smith #undef __FUNCT__ 2915b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 29167087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2917b271bb04SBarry Smith { 2918b271bb04SBarry Smith PetscErrorCode ierr; 2919b271bb04SBarry Smith 2920b271bb04SBarry Smith PetscFunctionBegin; 2921b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2922b271bb04SBarry Smith PetscFunctionReturn(0); 2923b271bb04SBarry Smith } 2924b271bb04SBarry Smith 2925b271bb04SBarry Smith #undef __FUNCT__ 2926b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 29276bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2928b271bb04SBarry Smith { 2929b271bb04SBarry Smith PetscErrorCode ierr; 2930b271bb04SBarry Smith 2931b271bb04SBarry Smith PetscFunctionBegin; 2932b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2933b271bb04SBarry Smith PetscFunctionReturn(0); 2934b271bb04SBarry Smith } 2935b271bb04SBarry Smith 29367a03ce2fSLisandro Dalcin #undef __FUNCT__ 29377a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 2938228d79bcSJed Brown /*@ 2939228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 2940228d79bcSJed Brown 2941228d79bcSJed Brown Collective on SNES 2942228d79bcSJed Brown 2943228d79bcSJed Brown Input Parameters: 2944228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 2945228d79bcSJed Brown . iter - iteration number 2946228d79bcSJed Brown - rnorm - relative norm of the residual 2947228d79bcSJed Brown 2948228d79bcSJed Brown Notes: 2949228d79bcSJed Brown This routine is called by the SNES implementations. 2950228d79bcSJed Brown It does not typically need to be called by the user. 2951228d79bcSJed Brown 2952228d79bcSJed Brown Level: developer 2953228d79bcSJed Brown 2954228d79bcSJed Brown .seealso: SNESMonitorSet() 2955228d79bcSJed Brown @*/ 29567a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 29577a03ce2fSLisandro Dalcin { 29587a03ce2fSLisandro Dalcin PetscErrorCode ierr; 29597a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 29607a03ce2fSLisandro Dalcin 29617a03ce2fSLisandro Dalcin PetscFunctionBegin; 29627a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 29637a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 29647a03ce2fSLisandro Dalcin } 29657a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 29667a03ce2fSLisandro Dalcin } 29677a03ce2fSLisandro Dalcin 29689b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 29699b94acceSBarry Smith 29704a2ae208SSatish Balay #undef __FUNCT__ 2971a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 29729b94acceSBarry Smith /*@C 2973a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 29749b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 29759b94acceSBarry Smith progress. 29769b94acceSBarry Smith 29773f9fe445SBarry Smith Logically Collective on SNES 2978fee21e36SBarry Smith 2979c7afd0dbSLois Curfman McInnes Input Parameters: 2980c7afd0dbSLois Curfman McInnes + snes - the SNES context 2981c7afd0dbSLois Curfman McInnes . func - monitoring routine 2982b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 2983e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 2984b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 2985b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 29869b94acceSBarry Smith 2987c7afd0dbSLois Curfman McInnes Calling sequence of func: 2988a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2989c7afd0dbSLois Curfman McInnes 2990c7afd0dbSLois Curfman McInnes + snes - the SNES context 2991c7afd0dbSLois Curfman McInnes . its - iteration number 2992c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 299340a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 29949b94acceSBarry Smith 29959665c990SLois Curfman McInnes Options Database Keys: 2996a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 2997a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 2998a6570f20SBarry Smith uses SNESMonitorLGCreate() 2999cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 3000c7afd0dbSLois Curfman McInnes been hardwired into a code by 3001a6570f20SBarry Smith calls to SNESMonitorSet(), but 3002c7afd0dbSLois Curfman McInnes does not cancel those set via 3003c7afd0dbSLois Curfman McInnes the options database. 30049665c990SLois Curfman McInnes 3005639f9d9dSBarry Smith Notes: 30066bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 3007a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 30086bc08f3fSLois Curfman McInnes order in which they were set. 3009639f9d9dSBarry Smith 3010025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 3011025f1a04SBarry Smith 301236851e7fSLois Curfman McInnes Level: intermediate 301336851e7fSLois Curfman McInnes 30149b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 30159b94acceSBarry Smith 3016a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 30179b94acceSBarry Smith @*/ 3018c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 30199b94acceSBarry Smith { 3020b90d0a6eSBarry Smith PetscInt i; 3021649052a6SBarry Smith PetscErrorCode ierr; 3022b90d0a6eSBarry Smith 30233a40ed3dSBarry Smith PetscFunctionBegin; 30240700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 302517186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 3026b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 3027649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 3028649052a6SBarry Smith if (monitordestroy) { 3029c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 3030649052a6SBarry Smith } 3031b90d0a6eSBarry Smith PetscFunctionReturn(0); 3032b90d0a6eSBarry Smith } 3033b90d0a6eSBarry Smith } 3034b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 3035b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 3036639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 30373a40ed3dSBarry Smith PetscFunctionReturn(0); 30389b94acceSBarry Smith } 30399b94acceSBarry Smith 30404a2ae208SSatish Balay #undef __FUNCT__ 3041a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 30425cd90555SBarry Smith /*@C 3043a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 30445cd90555SBarry Smith 30453f9fe445SBarry Smith Logically Collective on SNES 3046c7afd0dbSLois Curfman McInnes 30475cd90555SBarry Smith Input Parameters: 30485cd90555SBarry Smith . snes - the SNES context 30495cd90555SBarry Smith 30501a480d89SAdministrator Options Database Key: 3051a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 3052a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 3053c7afd0dbSLois Curfman McInnes set via the options database 30545cd90555SBarry Smith 30555cd90555SBarry Smith Notes: 30565cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 30575cd90555SBarry Smith 305836851e7fSLois Curfman McInnes Level: intermediate 305936851e7fSLois Curfman McInnes 30605cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 30615cd90555SBarry Smith 3062a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 30635cd90555SBarry Smith @*/ 30647087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 30655cd90555SBarry Smith { 3066d952e501SBarry Smith PetscErrorCode ierr; 3067d952e501SBarry Smith PetscInt i; 3068d952e501SBarry Smith 30695cd90555SBarry Smith PetscFunctionBegin; 30700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3071d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 3072d952e501SBarry Smith if (snes->monitordestroy[i]) { 30733c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 3074d952e501SBarry Smith } 3075d952e501SBarry Smith } 30765cd90555SBarry Smith snes->numbermonitors = 0; 30775cd90555SBarry Smith PetscFunctionReturn(0); 30785cd90555SBarry Smith } 30795cd90555SBarry Smith 30804a2ae208SSatish Balay #undef __FUNCT__ 30814a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 30829b94acceSBarry Smith /*@C 30839b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 30849b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 30859b94acceSBarry Smith 30863f9fe445SBarry Smith Logically Collective on SNES 3087fee21e36SBarry Smith 3088c7afd0dbSLois Curfman McInnes Input Parameters: 3089c7afd0dbSLois Curfman McInnes + snes - the SNES context 3090c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 30917f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 30927f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 30939b94acceSBarry Smith 3094c7afd0dbSLois Curfman McInnes Calling sequence of func: 309506ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 3096c7afd0dbSLois Curfman McInnes 3097c7afd0dbSLois Curfman McInnes + snes - the SNES context 309806ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 3099c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 3100184914b5SBarry Smith . reason - reason for convergence/divergence 3101c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 31024b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 31034b27c08aSLois Curfman McInnes - f - 2-norm of function 31049b94acceSBarry Smith 310536851e7fSLois Curfman McInnes Level: advanced 310636851e7fSLois Curfman McInnes 31079b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 31089b94acceSBarry Smith 310985385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 31109b94acceSBarry Smith @*/ 31117087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 31129b94acceSBarry Smith { 31137f7931b9SBarry Smith PetscErrorCode ierr; 31147f7931b9SBarry Smith 31153a40ed3dSBarry Smith PetscFunctionBegin; 31160700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 311785385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 31187f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 31197f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 31207f7931b9SBarry Smith } 312185385478SLisandro Dalcin snes->ops->converged = func; 31227f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 312385385478SLisandro Dalcin snes->cnvP = cctx; 31243a40ed3dSBarry Smith PetscFunctionReturn(0); 31259b94acceSBarry Smith } 31269b94acceSBarry Smith 31274a2ae208SSatish Balay #undef __FUNCT__ 31284a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 312952baeb72SSatish Balay /*@ 3130184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 3131184914b5SBarry Smith 3132184914b5SBarry Smith Not Collective 3133184914b5SBarry Smith 3134184914b5SBarry Smith Input Parameter: 3135184914b5SBarry Smith . snes - the SNES context 3136184914b5SBarry Smith 3137184914b5SBarry Smith Output Parameter: 31384d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 3139184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 3140184914b5SBarry Smith 3141184914b5SBarry Smith Level: intermediate 3142184914b5SBarry Smith 3143184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 3144184914b5SBarry Smith 3145184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 3146184914b5SBarry Smith 314785385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 3148184914b5SBarry Smith @*/ 31497087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 3150184914b5SBarry Smith { 3151184914b5SBarry Smith PetscFunctionBegin; 31520700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31534482741eSBarry Smith PetscValidPointer(reason,2); 3154184914b5SBarry Smith *reason = snes->reason; 3155184914b5SBarry Smith PetscFunctionReturn(0); 3156184914b5SBarry Smith } 3157184914b5SBarry Smith 31584a2ae208SSatish Balay #undef __FUNCT__ 31594a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 3160c9005455SLois Curfman McInnes /*@ 3161c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 3162c9005455SLois Curfman McInnes 31633f9fe445SBarry Smith Logically Collective on SNES 3164fee21e36SBarry Smith 3165c7afd0dbSLois Curfman McInnes Input Parameters: 3166c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 31678c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 3168cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 3169758f92a0SBarry Smith . na - size of a and its 317064731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 3171758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 3172c7afd0dbSLois Curfman McInnes 3173308dcc3eSBarry Smith Notes: 3174308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 3175308dcc3eSBarry Smith default array of length 10000 is allocated. 3176308dcc3eSBarry Smith 3177c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 3178c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 3179c9005455SLois Curfman McInnes during the section of code that is being timed. 3180c9005455SLois Curfman McInnes 318136851e7fSLois Curfman McInnes Level: intermediate 318236851e7fSLois Curfman McInnes 3183c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 3184758f92a0SBarry Smith 318508405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 3186758f92a0SBarry Smith 3187c9005455SLois Curfman McInnes @*/ 31887087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 3189c9005455SLois Curfman McInnes { 3190308dcc3eSBarry Smith PetscErrorCode ierr; 3191308dcc3eSBarry Smith 31923a40ed3dSBarry Smith PetscFunctionBegin; 31930700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31944482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 3195a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 3196308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 3197308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 3198308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 3199308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 3200308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 3201308dcc3eSBarry Smith } 3202c9005455SLois Curfman McInnes snes->conv_hist = a; 3203758f92a0SBarry Smith snes->conv_hist_its = its; 3204758f92a0SBarry Smith snes->conv_hist_max = na; 3205a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 3206758f92a0SBarry Smith snes->conv_hist_reset = reset; 3207758f92a0SBarry Smith PetscFunctionReturn(0); 3208758f92a0SBarry Smith } 3209758f92a0SBarry Smith 3210308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3211c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 3212c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 3213308dcc3eSBarry Smith EXTERN_C_BEGIN 3214308dcc3eSBarry Smith #undef __FUNCT__ 3215308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 3216308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3217308dcc3eSBarry Smith { 3218308dcc3eSBarry Smith mxArray *mat; 3219308dcc3eSBarry Smith PetscInt i; 3220308dcc3eSBarry Smith PetscReal *ar; 3221308dcc3eSBarry Smith 3222308dcc3eSBarry Smith PetscFunctionBegin; 3223308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3224308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3225308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 3226308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 3227308dcc3eSBarry Smith } 3228308dcc3eSBarry Smith PetscFunctionReturn(mat); 3229308dcc3eSBarry Smith } 3230308dcc3eSBarry Smith EXTERN_C_END 3231308dcc3eSBarry Smith #endif 3232308dcc3eSBarry Smith 3233308dcc3eSBarry Smith 32344a2ae208SSatish Balay #undef __FUNCT__ 32354a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 32360c4c9dddSBarry Smith /*@C 3237758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3238758f92a0SBarry Smith 32393f9fe445SBarry Smith Not Collective 3240758f92a0SBarry Smith 3241758f92a0SBarry Smith Input Parameter: 3242758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3243758f92a0SBarry Smith 3244758f92a0SBarry Smith Output Parameters: 3245758f92a0SBarry Smith . a - array to hold history 3246758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3247758f92a0SBarry Smith negative if not converged) for each solve. 3248758f92a0SBarry Smith - na - size of a and its 3249758f92a0SBarry Smith 3250758f92a0SBarry Smith Notes: 3251758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3252758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3253758f92a0SBarry Smith 3254758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3255758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3256758f92a0SBarry Smith during the section of code that is being timed. 3257758f92a0SBarry Smith 3258758f92a0SBarry Smith Level: intermediate 3259758f92a0SBarry Smith 3260758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3261758f92a0SBarry Smith 3262758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3263758f92a0SBarry Smith 3264758f92a0SBarry Smith @*/ 32657087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3266758f92a0SBarry Smith { 3267758f92a0SBarry Smith PetscFunctionBegin; 32680700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3269758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3270758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3271758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 32723a40ed3dSBarry Smith PetscFunctionReturn(0); 3273c9005455SLois Curfman McInnes } 3274c9005455SLois Curfman McInnes 3275e74ef692SMatthew Knepley #undef __FUNCT__ 3276e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 3277ac226902SBarry Smith /*@C 327876b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3279eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 32807e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 328176b2cf59SMatthew Knepley 32823f9fe445SBarry Smith Logically Collective on SNES 328376b2cf59SMatthew Knepley 328476b2cf59SMatthew Knepley Input Parameters: 328576b2cf59SMatthew Knepley . snes - The nonlinear solver context 328676b2cf59SMatthew Knepley . func - The function 328776b2cf59SMatthew Knepley 328876b2cf59SMatthew Knepley Calling sequence of func: 3289b5d30489SBarry Smith . func (SNES snes, PetscInt step); 329076b2cf59SMatthew Knepley 329176b2cf59SMatthew Knepley . step - The current step of the iteration 329276b2cf59SMatthew Knepley 3293fe97e370SBarry Smith Level: advanced 3294fe97e370SBarry Smith 3295fe97e370SBarry 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() 3296fe97e370SBarry Smith This is not used by most users. 329776b2cf59SMatthew Knepley 329876b2cf59SMatthew Knepley .keywords: SNES, update 3299b5d30489SBarry Smith 330085385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 330176b2cf59SMatthew Knepley @*/ 33027087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 330376b2cf59SMatthew Knepley { 330476b2cf59SMatthew Knepley PetscFunctionBegin; 33050700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3306e7788613SBarry Smith snes->ops->update = func; 330776b2cf59SMatthew Knepley PetscFunctionReturn(0); 330876b2cf59SMatthew Knepley } 330976b2cf59SMatthew Knepley 3310e74ef692SMatthew Knepley #undef __FUNCT__ 3311e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 331276b2cf59SMatthew Knepley /*@ 331376b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 331476b2cf59SMatthew Knepley 331576b2cf59SMatthew Knepley Not collective 331676b2cf59SMatthew Knepley 331776b2cf59SMatthew Knepley Input Parameters: 331876b2cf59SMatthew Knepley . snes - The nonlinear solver context 331976b2cf59SMatthew Knepley . step - The current step of the iteration 332076b2cf59SMatthew Knepley 3321205452f4SMatthew Knepley Level: intermediate 3322205452f4SMatthew Knepley 332376b2cf59SMatthew Knepley .keywords: SNES, update 3324a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 332576b2cf59SMatthew Knepley @*/ 33267087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 332776b2cf59SMatthew Knepley { 332876b2cf59SMatthew Knepley PetscFunctionBegin; 332976b2cf59SMatthew Knepley PetscFunctionReturn(0); 333076b2cf59SMatthew Knepley } 333176b2cf59SMatthew Knepley 33324a2ae208SSatish Balay #undef __FUNCT__ 33334a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 33349b94acceSBarry Smith /* 33359b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 33369b94acceSBarry Smith positive parameter delta. 33379b94acceSBarry Smith 33389b94acceSBarry Smith Input Parameters: 3339c7afd0dbSLois Curfman McInnes + snes - the SNES context 33409b94acceSBarry Smith . y - approximate solution of linear system 33419b94acceSBarry Smith . fnorm - 2-norm of current function 3342c7afd0dbSLois Curfman McInnes - delta - trust region size 33439b94acceSBarry Smith 33449b94acceSBarry Smith Output Parameters: 3345c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 33469b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 33479b94acceSBarry Smith region, and exceeds zero otherwise. 3348c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 33499b94acceSBarry Smith 33509b94acceSBarry Smith Note: 33514b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 33529b94acceSBarry Smith is set to be the maximum allowable step size. 33539b94acceSBarry Smith 33549b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 33559b94acceSBarry Smith */ 3356dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 33579b94acceSBarry Smith { 3358064f8208SBarry Smith PetscReal nrm; 3359ea709b57SSatish Balay PetscScalar cnorm; 3360dfbe8321SBarry Smith PetscErrorCode ierr; 33613a40ed3dSBarry Smith 33623a40ed3dSBarry Smith PetscFunctionBegin; 33630700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 33640700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3365c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3366184914b5SBarry Smith 3367064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3368064f8208SBarry Smith if (nrm > *delta) { 3369064f8208SBarry Smith nrm = *delta/nrm; 3370064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3371064f8208SBarry Smith cnorm = nrm; 33722dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 33739b94acceSBarry Smith *ynorm = *delta; 33749b94acceSBarry Smith } else { 33759b94acceSBarry Smith *gpnorm = 0.0; 3376064f8208SBarry Smith *ynorm = nrm; 33779b94acceSBarry Smith } 33783a40ed3dSBarry Smith PetscFunctionReturn(0); 33799b94acceSBarry Smith } 33809b94acceSBarry Smith 33814a2ae208SSatish Balay #undef __FUNCT__ 33824a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 33836ce558aeSBarry Smith /*@C 3384f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3385f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 33869b94acceSBarry Smith 3387c7afd0dbSLois Curfman McInnes Collective on SNES 3388c7afd0dbSLois Curfman McInnes 3389b2002411SLois Curfman McInnes Input Parameters: 3390c7afd0dbSLois Curfman McInnes + snes - the SNES context 33913cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 339285385478SLisandro Dalcin - x - the solution vector. 33939b94acceSBarry Smith 3394b2002411SLois Curfman McInnes Notes: 33958ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 33968ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 33978ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 33988ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 33998ddd3da0SLois Curfman McInnes 340036851e7fSLois Curfman McInnes Level: beginner 340136851e7fSLois Curfman McInnes 34029b94acceSBarry Smith .keywords: SNES, nonlinear, solve 34039b94acceSBarry Smith 3404c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 34059b94acceSBarry Smith @*/ 34067087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 34079b94acceSBarry Smith { 3408dfbe8321SBarry Smith PetscErrorCode ierr; 3409ace3abfcSBarry Smith PetscBool flg; 3410eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 3411eabae89aSBarry Smith PetscViewer viewer; 3412efd51863SBarry Smith PetscInt grid; 3413a69afd8bSBarry Smith Vec xcreated = PETSC_NULL; 3414caa4e7f2SJed Brown DM dm; 3415052efed2SBarry Smith 34163a40ed3dSBarry Smith PetscFunctionBegin; 34170700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3418a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3419a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 34200700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 342185385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 342285385478SLisandro Dalcin 3423caa4e7f2SJed Brown if (!x) { 3424caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3425caa4e7f2SJed Brown ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 3426a69afd8bSBarry Smith x = xcreated; 3427a69afd8bSBarry Smith } 3428a69afd8bSBarry Smith 3429a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3430efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3431efd51863SBarry Smith 343285385478SLisandro Dalcin /* set solution vector */ 3433efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 34346bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 343585385478SLisandro Dalcin snes->vec_sol = x; 3436caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3437caa4e7f2SJed Brown 3438caa4e7f2SJed Brown /* set affine vector if provided */ 343985385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 34406bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 344185385478SLisandro Dalcin snes->vec_rhs = b; 344285385478SLisandro Dalcin 344370e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 34443f149594SLisandro Dalcin 34457eee914bSBarry Smith if (!grid) { 34467eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3447d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3448dd568438SSatish Balay } else if (snes->dm) { 3449dd568438SSatish Balay PetscBool ig; 3450dd568438SSatish Balay ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr); 3451dd568438SSatish Balay if (ig) { 34527eee914bSBarry Smith ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr); 34537eee914bSBarry Smith } 3454d25893d9SBarry Smith } 3455dd568438SSatish Balay } 3456d25893d9SBarry Smith 3457abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 345850ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3459d5e45103SBarry Smith 34603f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 34614936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 346285385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 34634936397dSBarry Smith if (snes->domainerror){ 34644936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 34654936397dSBarry Smith snes->domainerror = PETSC_FALSE; 34664936397dSBarry Smith } 346717186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 34683f149594SLisandro Dalcin 346990d69ab7SBarry Smith flg = PETSC_FALSE; 3470acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3471da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 34725968eb51SBarry Smith if (snes->printreason) { 3473a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 34745968eb51SBarry Smith if (snes->reason > 0) { 3475c7e7b494SJed 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); 34765968eb51SBarry Smith } else { 3477c7e7b494SJed 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); 34785968eb51SBarry Smith } 3479a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 34805968eb51SBarry Smith } 34815968eb51SBarry Smith 3482e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3483efd51863SBarry Smith if (grid < snes->gridsequence) { 3484efd51863SBarry Smith DM fine; 3485efd51863SBarry Smith Vec xnew; 3486efd51863SBarry Smith Mat interp; 3487efd51863SBarry Smith 3488efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3489c5c77316SJed Brown if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 3490e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3491efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3492efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3493c833c3b5SJed Brown ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr); 3494efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3495efd51863SBarry Smith x = xnew; 3496efd51863SBarry Smith 3497efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3498efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3499efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3500a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3501efd51863SBarry Smith } 3502efd51863SBarry Smith } 3503*3f7e2da0SPeter Brune /* monitoring and viewing */ 3504*3f7e2da0SPeter Brune flg = PETSC_FALSE; 3505*3f7e2da0SPeter Brune ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 3506*3f7e2da0SPeter Brune if (flg && !PetscPreLoadingOn) { 3507*3f7e2da0SPeter Brune ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 3508*3f7e2da0SPeter Brune ierr = SNESView(snes,viewer);CHKERRQ(ierr); 3509*3f7e2da0SPeter Brune ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3510*3f7e2da0SPeter Brune } 3511*3f7e2da0SPeter Brune 3512*3f7e2da0SPeter Brune flg = PETSC_FALSE; 3513*3f7e2da0SPeter Brune ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 3514*3f7e2da0SPeter Brune if (flg) { 3515*3f7e2da0SPeter Brune PetscViewer viewer; 3516*3f7e2da0SPeter Brune ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 3517*3f7e2da0SPeter Brune ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 3518*3f7e2da0SPeter Brune ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 3519*3f7e2da0SPeter Brune ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 3520*3f7e2da0SPeter Brune ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3521*3f7e2da0SPeter Brune } 3522*3f7e2da0SPeter Brune 3523a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 35243a40ed3dSBarry Smith PetscFunctionReturn(0); 35259b94acceSBarry Smith } 35269b94acceSBarry Smith 35279b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 35289b94acceSBarry Smith 35294a2ae208SSatish Balay #undef __FUNCT__ 35304a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 353182bf6240SBarry Smith /*@C 35324b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 35339b94acceSBarry Smith 3534fee21e36SBarry Smith Collective on SNES 3535fee21e36SBarry Smith 3536c7afd0dbSLois Curfman McInnes Input Parameters: 3537c7afd0dbSLois Curfman McInnes + snes - the SNES context 3538454a90a3SBarry Smith - type - a known method 3539c7afd0dbSLois Curfman McInnes 3540c7afd0dbSLois Curfman McInnes Options Database Key: 3541454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3542c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3543ae12b187SLois Curfman McInnes 35449b94acceSBarry Smith Notes: 3545e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 35464b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3547c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 35484b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3549c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 35509b94acceSBarry Smith 3551ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3552ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3553ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3554ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3555ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3556ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3557ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3558ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3559ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3560b0a32e0cSBarry Smith appropriate method. 356136851e7fSLois Curfman McInnes 356236851e7fSLois Curfman McInnes Level: intermediate 3563a703fe33SLois Curfman McInnes 3564454a90a3SBarry Smith .keywords: SNES, set, type 3565435da068SBarry Smith 3566435da068SBarry Smith .seealso: SNESType, SNESCreate() 3567435da068SBarry Smith 35689b94acceSBarry Smith @*/ 35697087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 35709b94acceSBarry Smith { 3571dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3572ace3abfcSBarry Smith PetscBool match; 35733a40ed3dSBarry Smith 35743a40ed3dSBarry Smith PetscFunctionBegin; 35750700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35764482741eSBarry Smith PetscValidCharPointer(type,2); 357782bf6240SBarry Smith 3578251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 35790f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 358092ff6ae8SBarry Smith 35814b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3582e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 358375396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 3584b5c23020SJed Brown if (snes->ops->destroy) { 3585b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 3586b5c23020SJed Brown snes->ops->destroy = PETSC_NULL; 3587b5c23020SJed Brown } 358875396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 358975396ef9SLisandro Dalcin snes->ops->setup = 0; 359075396ef9SLisandro Dalcin snes->ops->solve = 0; 359175396ef9SLisandro Dalcin snes->ops->view = 0; 359275396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 359375396ef9SLisandro Dalcin snes->ops->destroy = 0; 359475396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 359575396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3596454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 359703bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 35989fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 35999fb22e1aSBarry Smith if (PetscAMSPublishAll) { 36009fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 36019fb22e1aSBarry Smith } 36029fb22e1aSBarry Smith #endif 36033a40ed3dSBarry Smith PetscFunctionReturn(0); 36049b94acceSBarry Smith } 36059b94acceSBarry Smith 3606a847f771SSatish Balay 36079b94acceSBarry Smith /* --------------------------------------------------------------------- */ 36084a2ae208SSatish Balay #undef __FUNCT__ 36094a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 361052baeb72SSatish Balay /*@ 36119b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3612f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 36139b94acceSBarry Smith 3614fee21e36SBarry Smith Not Collective 3615fee21e36SBarry Smith 361636851e7fSLois Curfman McInnes Level: advanced 361736851e7fSLois Curfman McInnes 36189b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 36199b94acceSBarry Smith 36209b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 36219b94acceSBarry Smith @*/ 36227087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 36239b94acceSBarry Smith { 3624dfbe8321SBarry Smith PetscErrorCode ierr; 362582bf6240SBarry Smith 36263a40ed3dSBarry Smith PetscFunctionBegin; 36271441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 36284c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 36293a40ed3dSBarry Smith PetscFunctionReturn(0); 36309b94acceSBarry Smith } 36319b94acceSBarry Smith 36324a2ae208SSatish Balay #undef __FUNCT__ 36334a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 36349b94acceSBarry Smith /*@C 36359a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 36369b94acceSBarry Smith 3637c7afd0dbSLois Curfman McInnes Not Collective 3638c7afd0dbSLois Curfman McInnes 36399b94acceSBarry Smith Input Parameter: 36404b0e389bSBarry Smith . snes - nonlinear solver context 36419b94acceSBarry Smith 36429b94acceSBarry Smith Output Parameter: 36433a7fca6bSBarry Smith . type - SNES method (a character string) 36449b94acceSBarry Smith 364536851e7fSLois Curfman McInnes Level: intermediate 364636851e7fSLois Curfman McInnes 3647454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 36489b94acceSBarry Smith @*/ 36497087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 36509b94acceSBarry Smith { 36513a40ed3dSBarry Smith PetscFunctionBegin; 36520700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36534482741eSBarry Smith PetscValidPointer(type,2); 36547adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 36553a40ed3dSBarry Smith PetscFunctionReturn(0); 36569b94acceSBarry Smith } 36579b94acceSBarry Smith 36584a2ae208SSatish Balay #undef __FUNCT__ 36594a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 366052baeb72SSatish Balay /*@ 36619b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3662c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 36639b94acceSBarry Smith 3664c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3665c7afd0dbSLois Curfman McInnes 36669b94acceSBarry Smith Input Parameter: 36679b94acceSBarry Smith . snes - the SNES context 36689b94acceSBarry Smith 36699b94acceSBarry Smith Output Parameter: 36709b94acceSBarry Smith . x - the solution 36719b94acceSBarry Smith 367270e92668SMatthew Knepley Level: intermediate 367336851e7fSLois Curfman McInnes 36749b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 36759b94acceSBarry Smith 367685385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 36779b94acceSBarry Smith @*/ 36787087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 36799b94acceSBarry Smith { 36803a40ed3dSBarry Smith PetscFunctionBegin; 36810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36824482741eSBarry Smith PetscValidPointer(x,2); 368385385478SLisandro Dalcin *x = snes->vec_sol; 368470e92668SMatthew Knepley PetscFunctionReturn(0); 368570e92668SMatthew Knepley } 368670e92668SMatthew Knepley 368770e92668SMatthew Knepley #undef __FUNCT__ 36884a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 368952baeb72SSatish Balay /*@ 36909b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 36919b94acceSBarry Smith stored. 36929b94acceSBarry Smith 3693c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3694c7afd0dbSLois Curfman McInnes 36959b94acceSBarry Smith Input Parameter: 36969b94acceSBarry Smith . snes - the SNES context 36979b94acceSBarry Smith 36989b94acceSBarry Smith Output Parameter: 36999b94acceSBarry Smith . x - the solution update 37009b94acceSBarry Smith 370136851e7fSLois Curfman McInnes Level: advanced 370236851e7fSLois Curfman McInnes 37039b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 37049b94acceSBarry Smith 370585385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 37069b94acceSBarry Smith @*/ 37077087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 37089b94acceSBarry Smith { 37093a40ed3dSBarry Smith PetscFunctionBegin; 37100700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37114482741eSBarry Smith PetscValidPointer(x,2); 371285385478SLisandro Dalcin *x = snes->vec_sol_update; 37133a40ed3dSBarry Smith PetscFunctionReturn(0); 37149b94acceSBarry Smith } 37159b94acceSBarry Smith 37164a2ae208SSatish Balay #undef __FUNCT__ 37174a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 37189b94acceSBarry Smith /*@C 37193638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 37209b94acceSBarry Smith 3721a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 3722c7afd0dbSLois Curfman McInnes 37239b94acceSBarry Smith Input Parameter: 37249b94acceSBarry Smith . snes - the SNES context 37259b94acceSBarry Smith 37269b94acceSBarry Smith Output Parameter: 37277bf4e008SBarry Smith + r - the function (or PETSC_NULL) 372870e92668SMatthew Knepley . func - the function (or PETSC_NULL) 372970e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 37309b94acceSBarry Smith 373136851e7fSLois Curfman McInnes Level: advanced 373236851e7fSLois Curfman McInnes 3733a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 37349b94acceSBarry Smith 37354b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 37369b94acceSBarry Smith @*/ 37377087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 37389b94acceSBarry Smith { 3739a63bb30eSJed Brown PetscErrorCode ierr; 37406cab3a1bSJed Brown DM dm; 3741a63bb30eSJed Brown 37423a40ed3dSBarry Smith PetscFunctionBegin; 37430700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3744a63bb30eSJed Brown if (r) { 3745a63bb30eSJed Brown if (!snes->vec_func) { 3746a63bb30eSJed Brown if (snes->vec_rhs) { 3747a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 3748a63bb30eSJed Brown } else if (snes->vec_sol) { 3749a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 3750a63bb30eSJed Brown } else if (snes->dm) { 3751a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 3752a63bb30eSJed Brown } 3753a63bb30eSJed Brown } 3754a63bb30eSJed Brown *r = snes->vec_func; 3755a63bb30eSJed Brown } 37566cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 37576cab3a1bSJed Brown ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr); 37583a40ed3dSBarry Smith PetscFunctionReturn(0); 37599b94acceSBarry Smith } 37609b94acceSBarry Smith 3761c79ef259SPeter Brune /*@C 3762c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3763c79ef259SPeter Brune 3764c79ef259SPeter Brune Input Parameter: 3765c79ef259SPeter Brune . snes - the SNES context 3766c79ef259SPeter Brune 3767c79ef259SPeter Brune Output Parameter: 3768c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3769c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3770c79ef259SPeter Brune 3771c79ef259SPeter Brune Level: advanced 3772c79ef259SPeter Brune 3773c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3774c79ef259SPeter Brune 3775c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3776c79ef259SPeter Brune @*/ 3777c79ef259SPeter Brune 37784a2ae208SSatish Balay #undef __FUNCT__ 3779646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3780646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3781646217ecSPeter Brune { 37826cab3a1bSJed Brown PetscErrorCode ierr; 37836cab3a1bSJed Brown DM dm; 37846cab3a1bSJed Brown 3785646217ecSPeter Brune PetscFunctionBegin; 3786646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37876cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 37886cab3a1bSJed Brown ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr); 3789646217ecSPeter Brune PetscFunctionReturn(0); 3790646217ecSPeter Brune } 3791646217ecSPeter Brune 37924a2ae208SSatish Balay #undef __FUNCT__ 37934a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 37943c7409f5SSatish Balay /*@C 37953c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3796d850072dSLois Curfman McInnes SNES options in the database. 37973c7409f5SSatish Balay 37983f9fe445SBarry Smith Logically Collective on SNES 3799fee21e36SBarry Smith 3800c7afd0dbSLois Curfman McInnes Input Parameter: 3801c7afd0dbSLois Curfman McInnes + snes - the SNES context 3802c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3803c7afd0dbSLois Curfman McInnes 3804d850072dSLois Curfman McInnes Notes: 3805a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3806c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3807d850072dSLois Curfman McInnes 380836851e7fSLois Curfman McInnes Level: advanced 380936851e7fSLois Curfman McInnes 38103c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3811a86d99e1SLois Curfman McInnes 3812a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 38133c7409f5SSatish Balay @*/ 38147087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 38153c7409f5SSatish Balay { 3816dfbe8321SBarry Smith PetscErrorCode ierr; 38173c7409f5SSatish Balay 38183a40ed3dSBarry Smith PetscFunctionBegin; 38190700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3820639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 38211cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 382294b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 38233a40ed3dSBarry Smith PetscFunctionReturn(0); 38243c7409f5SSatish Balay } 38253c7409f5SSatish Balay 38264a2ae208SSatish Balay #undef __FUNCT__ 38274a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 38283c7409f5SSatish Balay /*@C 3829f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3830d850072dSLois Curfman McInnes SNES options in the database. 38313c7409f5SSatish Balay 38323f9fe445SBarry Smith Logically Collective on SNES 3833fee21e36SBarry Smith 3834c7afd0dbSLois Curfman McInnes Input Parameters: 3835c7afd0dbSLois Curfman McInnes + snes - the SNES context 3836c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3837c7afd0dbSLois Curfman McInnes 3838d850072dSLois Curfman McInnes Notes: 3839a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3840c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3841d850072dSLois Curfman McInnes 384236851e7fSLois Curfman McInnes Level: advanced 384336851e7fSLois Curfman McInnes 38443c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3845a86d99e1SLois Curfman McInnes 3846a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 38473c7409f5SSatish Balay @*/ 38487087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 38493c7409f5SSatish Balay { 3850dfbe8321SBarry Smith PetscErrorCode ierr; 38513c7409f5SSatish Balay 38523a40ed3dSBarry Smith PetscFunctionBegin; 38530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3854639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 38551cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 385694b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 38573a40ed3dSBarry Smith PetscFunctionReturn(0); 38583c7409f5SSatish Balay } 38593c7409f5SSatish Balay 38604a2ae208SSatish Balay #undef __FUNCT__ 38614a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 38629ab63eb5SSatish Balay /*@C 38633c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 38643c7409f5SSatish Balay SNES options in the database. 38653c7409f5SSatish Balay 3866c7afd0dbSLois Curfman McInnes Not Collective 3867c7afd0dbSLois Curfman McInnes 38683c7409f5SSatish Balay Input Parameter: 38693c7409f5SSatish Balay . snes - the SNES context 38703c7409f5SSatish Balay 38713c7409f5SSatish Balay Output Parameter: 38723c7409f5SSatish Balay . prefix - pointer to the prefix string used 38733c7409f5SSatish Balay 38744ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 38759ab63eb5SSatish Balay sufficient length to hold the prefix. 38769ab63eb5SSatish Balay 387736851e7fSLois Curfman McInnes Level: advanced 387836851e7fSLois Curfman McInnes 38793c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 3880a86d99e1SLois Curfman McInnes 3881a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 38823c7409f5SSatish Balay @*/ 38837087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 38843c7409f5SSatish Balay { 3885dfbe8321SBarry Smith PetscErrorCode ierr; 38863c7409f5SSatish Balay 38873a40ed3dSBarry Smith PetscFunctionBegin; 38880700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3889639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 38903a40ed3dSBarry Smith PetscFunctionReturn(0); 38913c7409f5SSatish Balay } 38923c7409f5SSatish Balay 3893b2002411SLois Curfman McInnes 38944a2ae208SSatish Balay #undef __FUNCT__ 38954a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 38963cea93caSBarry Smith /*@C 38973cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 38983cea93caSBarry Smith 38997f6c08e0SMatthew Knepley Level: advanced 39003cea93caSBarry Smith @*/ 39017087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3902b2002411SLois Curfman McInnes { 3903e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3904dfbe8321SBarry Smith PetscErrorCode ierr; 3905b2002411SLois Curfman McInnes 3906b2002411SLois Curfman McInnes PetscFunctionBegin; 3907b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3908c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3909b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3910b2002411SLois Curfman McInnes } 3911da9b6338SBarry Smith 3912da9b6338SBarry Smith #undef __FUNCT__ 3913da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 39147087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3915da9b6338SBarry Smith { 3916dfbe8321SBarry Smith PetscErrorCode ierr; 391777431f27SBarry Smith PetscInt N,i,j; 3918da9b6338SBarry Smith Vec u,uh,fh; 3919da9b6338SBarry Smith PetscScalar value; 3920da9b6338SBarry Smith PetscReal norm; 3921da9b6338SBarry Smith 3922da9b6338SBarry Smith PetscFunctionBegin; 3923da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3924da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3925da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3926da9b6338SBarry Smith 3927da9b6338SBarry Smith /* currently only works for sequential */ 3928da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3929da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3930da9b6338SBarry Smith for (i=0; i<N; i++) { 3931da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 393277431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3933da9b6338SBarry Smith for (j=-10; j<11; j++) { 3934ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3935da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 39363ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3937da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 393877431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3939da9b6338SBarry Smith value = -value; 3940da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3941da9b6338SBarry Smith } 3942da9b6338SBarry Smith } 39436bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 39446bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 3945da9b6338SBarry Smith PetscFunctionReturn(0); 3946da9b6338SBarry Smith } 394771f87433Sdalcinl 394871f87433Sdalcinl #undef __FUNCT__ 3949fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 395071f87433Sdalcinl /*@ 3951fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 395271f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 395371f87433Sdalcinl Newton method. 395471f87433Sdalcinl 39553f9fe445SBarry Smith Logically Collective on SNES 395671f87433Sdalcinl 395771f87433Sdalcinl Input Parameters: 395871f87433Sdalcinl + snes - SNES context 395971f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 396071f87433Sdalcinl 396164ba62caSBarry Smith Options Database: 396264ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 396364ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 396464ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 396564ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 396664ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 396764ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 396864ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 396964ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 397064ba62caSBarry Smith 397171f87433Sdalcinl Notes: 397271f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 397371f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 397471f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 397571f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 397671f87433Sdalcinl solver. 397771f87433Sdalcinl 397871f87433Sdalcinl Level: advanced 397971f87433Sdalcinl 398071f87433Sdalcinl Reference: 398171f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 398271f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 398371f87433Sdalcinl 398471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 398571f87433Sdalcinl 3986fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 398771f87433Sdalcinl @*/ 39887087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 398971f87433Sdalcinl { 399071f87433Sdalcinl PetscFunctionBegin; 39910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3992acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 399371f87433Sdalcinl snes->ksp_ewconv = flag; 399471f87433Sdalcinl PetscFunctionReturn(0); 399571f87433Sdalcinl } 399671f87433Sdalcinl 399771f87433Sdalcinl #undef __FUNCT__ 3998fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 399971f87433Sdalcinl /*@ 4000fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 400171f87433Sdalcinl for computing relative tolerance for linear solvers within an 400271f87433Sdalcinl inexact Newton method. 400371f87433Sdalcinl 400471f87433Sdalcinl Not Collective 400571f87433Sdalcinl 400671f87433Sdalcinl Input Parameter: 400771f87433Sdalcinl . snes - SNES context 400871f87433Sdalcinl 400971f87433Sdalcinl Output Parameter: 401071f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 401171f87433Sdalcinl 401271f87433Sdalcinl Notes: 401371f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 401471f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 401571f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 401671f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 401771f87433Sdalcinl solver. 401871f87433Sdalcinl 401971f87433Sdalcinl Level: advanced 402071f87433Sdalcinl 402171f87433Sdalcinl Reference: 402271f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 402371f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 402471f87433Sdalcinl 402571f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 402671f87433Sdalcinl 4027fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 402871f87433Sdalcinl @*/ 40297087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 403071f87433Sdalcinl { 403171f87433Sdalcinl PetscFunctionBegin; 40320700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 403371f87433Sdalcinl PetscValidPointer(flag,2); 403471f87433Sdalcinl *flag = snes->ksp_ewconv; 403571f87433Sdalcinl PetscFunctionReturn(0); 403671f87433Sdalcinl } 403771f87433Sdalcinl 403871f87433Sdalcinl #undef __FUNCT__ 4039fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 404071f87433Sdalcinl /*@ 4041fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 404271f87433Sdalcinl convergence criteria for the linear solvers within an inexact 404371f87433Sdalcinl Newton method. 404471f87433Sdalcinl 40453f9fe445SBarry Smith Logically Collective on SNES 404671f87433Sdalcinl 404771f87433Sdalcinl Input Parameters: 404871f87433Sdalcinl + snes - SNES context 404971f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 405071f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 405171f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 405271f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 405371f87433Sdalcinl (0 <= gamma2 <= 1) 405471f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 405571f87433Sdalcinl . alpha2 - power for safeguard 405671f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 405771f87433Sdalcinl 405871f87433Sdalcinl Note: 405971f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 406071f87433Sdalcinl 406171f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 406271f87433Sdalcinl 406371f87433Sdalcinl Level: advanced 406471f87433Sdalcinl 406571f87433Sdalcinl Reference: 406671f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 406771f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 406871f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 406971f87433Sdalcinl 407071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 407171f87433Sdalcinl 4072fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 407371f87433Sdalcinl @*/ 40747087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 407571f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 407671f87433Sdalcinl { 4077fa9f3622SBarry Smith SNESKSPEW *kctx; 407871f87433Sdalcinl PetscFunctionBegin; 40790700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4080fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4081e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 4082c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 4083c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 4084c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 4085c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 4086c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 4087c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 4088c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 408971f87433Sdalcinl 409071f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 409171f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 409271f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 409371f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 409471f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 409571f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 409671f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 409771f87433Sdalcinl 409871f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 4099e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 410071f87433Sdalcinl } 410171f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 4102e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 410371f87433Sdalcinl } 410471f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 4105e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 410671f87433Sdalcinl } 410771f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 4108e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 410971f87433Sdalcinl } 411071f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 4111e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 411271f87433Sdalcinl } 411371f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 4114e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 411571f87433Sdalcinl } 411671f87433Sdalcinl PetscFunctionReturn(0); 411771f87433Sdalcinl } 411871f87433Sdalcinl 411971f87433Sdalcinl #undef __FUNCT__ 4120fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 412171f87433Sdalcinl /*@ 4122fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 412371f87433Sdalcinl convergence criteria for the linear solvers within an inexact 412471f87433Sdalcinl Newton method. 412571f87433Sdalcinl 412671f87433Sdalcinl Not Collective 412771f87433Sdalcinl 412871f87433Sdalcinl Input Parameters: 412971f87433Sdalcinl snes - SNES context 413071f87433Sdalcinl 413171f87433Sdalcinl Output Parameters: 413271f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 413371f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 413471f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 413571f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 413671f87433Sdalcinl (0 <= gamma2 <= 1) 413771f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 413871f87433Sdalcinl . alpha2 - power for safeguard 413971f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 414071f87433Sdalcinl 414171f87433Sdalcinl Level: advanced 414271f87433Sdalcinl 414371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 414471f87433Sdalcinl 4145fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 414671f87433Sdalcinl @*/ 41477087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 414871f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 414971f87433Sdalcinl { 4150fa9f3622SBarry Smith SNESKSPEW *kctx; 415171f87433Sdalcinl PetscFunctionBegin; 41520700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4153fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4154e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 415571f87433Sdalcinl if(version) *version = kctx->version; 415671f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 415771f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 415871f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 415971f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 416071f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 416171f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 416271f87433Sdalcinl PetscFunctionReturn(0); 416371f87433Sdalcinl } 416471f87433Sdalcinl 416571f87433Sdalcinl #undef __FUNCT__ 4166fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 4167fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 416871f87433Sdalcinl { 416971f87433Sdalcinl PetscErrorCode ierr; 4170fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 417171f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 417271f87433Sdalcinl 417371f87433Sdalcinl PetscFunctionBegin; 4174e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 417571f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 417671f87433Sdalcinl rtol = kctx->rtol_0; 417771f87433Sdalcinl } else { 417871f87433Sdalcinl if (kctx->version == 1) { 417971f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 418071f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 418171f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 418271f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 418371f87433Sdalcinl } else if (kctx->version == 2) { 418471f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 418571f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 418671f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 418771f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 418871f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 418971f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 419071f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 419171f87433Sdalcinl stol = PetscMax(rtol,stol); 419271f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 419371f87433Sdalcinl /* safeguard: avoid oversolving */ 419471f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 419571f87433Sdalcinl stol = PetscMax(rtol,stol); 419671f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 4197e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 419871f87433Sdalcinl } 419971f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 420071f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 420171f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 420271f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 420371f87433Sdalcinl PetscFunctionReturn(0); 420471f87433Sdalcinl } 420571f87433Sdalcinl 420671f87433Sdalcinl #undef __FUNCT__ 4207fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 4208fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 420971f87433Sdalcinl { 421071f87433Sdalcinl PetscErrorCode ierr; 4211fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 421271f87433Sdalcinl PCSide pcside; 421371f87433Sdalcinl Vec lres; 421471f87433Sdalcinl 421571f87433Sdalcinl PetscFunctionBegin; 4216e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 421771f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 421871f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 421971f87433Sdalcinl if (kctx->version == 1) { 4220b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 422171f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 422271f87433Sdalcinl /* KSP residual is true linear residual */ 422371f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 422471f87433Sdalcinl } else { 422571f87433Sdalcinl /* KSP residual is preconditioned residual */ 422671f87433Sdalcinl /* compute true linear residual norm */ 422771f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 422871f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 422971f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 423071f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 42316bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 423271f87433Sdalcinl } 423371f87433Sdalcinl } 423471f87433Sdalcinl PetscFunctionReturn(0); 423571f87433Sdalcinl } 423671f87433Sdalcinl 423771f87433Sdalcinl #undef __FUNCT__ 423871f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 423971f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 424071f87433Sdalcinl { 424171f87433Sdalcinl PetscErrorCode ierr; 424271f87433Sdalcinl 424371f87433Sdalcinl PetscFunctionBegin; 4244fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 424571f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 4246fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 424771f87433Sdalcinl PetscFunctionReturn(0); 424871f87433Sdalcinl } 42496c699258SBarry Smith 42506c699258SBarry Smith #undef __FUNCT__ 42516c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 42526c699258SBarry Smith /*@ 42536c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 42546c699258SBarry Smith 42553f9fe445SBarry Smith Logically Collective on SNES 42566c699258SBarry Smith 42576c699258SBarry Smith Input Parameters: 42586c699258SBarry Smith + snes - the preconditioner context 42596c699258SBarry Smith - dm - the dm 42606c699258SBarry Smith 42616c699258SBarry Smith Level: intermediate 42626c699258SBarry Smith 42636c699258SBarry Smith 42646c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 42656c699258SBarry Smith @*/ 42667087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 42676c699258SBarry Smith { 42686c699258SBarry Smith PetscErrorCode ierr; 4269345fed2cSBarry Smith KSP ksp; 42706cab3a1bSJed Brown SNESDM sdm; 42716c699258SBarry Smith 42726c699258SBarry Smith PetscFunctionBegin; 42730700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4274d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 42756cab3a1bSJed Brown if (snes->dm) { /* Move the SNESDM context over to the new DM unless the new DM already has one */ 42766cab3a1bSJed Brown PetscContainer oldcontainer,container; 42776cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 42786cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr); 42796cab3a1bSJed Brown if (oldcontainer && !container) { 42806cab3a1bSJed Brown ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr); 42816cab3a1bSJed Brown ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr); 42826cab3a1bSJed Brown if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */ 42836cab3a1bSJed Brown sdm->originaldm = dm; 42846cab3a1bSJed Brown } 42856cab3a1bSJed Brown } 42866bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 42876cab3a1bSJed Brown } 42886c699258SBarry Smith snes->dm = dm; 4289345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4290345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4291f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 42922c155ee1SBarry Smith if (snes->pc) { 42932c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 42942c155ee1SBarry Smith } 42956c699258SBarry Smith PetscFunctionReturn(0); 42966c699258SBarry Smith } 42976c699258SBarry Smith 42986c699258SBarry Smith #undef __FUNCT__ 42996c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 43006c699258SBarry Smith /*@ 43016c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 43026c699258SBarry Smith 43033f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 43046c699258SBarry Smith 43056c699258SBarry Smith Input Parameter: 43066c699258SBarry Smith . snes - the preconditioner context 43076c699258SBarry Smith 43086c699258SBarry Smith Output Parameter: 43096c699258SBarry Smith . dm - the dm 43106c699258SBarry Smith 43116c699258SBarry Smith Level: intermediate 43126c699258SBarry Smith 43136c699258SBarry Smith 43146c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 43156c699258SBarry Smith @*/ 43167087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 43176c699258SBarry Smith { 43186cab3a1bSJed Brown PetscErrorCode ierr; 43196cab3a1bSJed Brown 43206c699258SBarry Smith PetscFunctionBegin; 43210700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 43226cab3a1bSJed Brown if (!snes->dm) { 43236cab3a1bSJed Brown ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr); 43246cab3a1bSJed Brown } 43256c699258SBarry Smith *dm = snes->dm; 43266c699258SBarry Smith PetscFunctionReturn(0); 43276c699258SBarry Smith } 43280807856dSBarry Smith 432931823bd8SMatthew G Knepley #undef __FUNCT__ 433031823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 433131823bd8SMatthew G Knepley /*@ 4332fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 433331823bd8SMatthew G Knepley 433431823bd8SMatthew G Knepley Collective on SNES 433531823bd8SMatthew G Knepley 433631823bd8SMatthew G Knepley Input Parameters: 433731823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 433831823bd8SMatthew G Knepley - pc - the preconditioner object 433931823bd8SMatthew G Knepley 434031823bd8SMatthew G Knepley Notes: 434131823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 434231823bd8SMatthew G Knepley to configure it using the API). 434331823bd8SMatthew G Knepley 434431823bd8SMatthew G Knepley Level: developer 434531823bd8SMatthew G Knepley 434631823bd8SMatthew G Knepley .keywords: SNES, set, precondition 434731823bd8SMatthew G Knepley .seealso: SNESGetPC() 434831823bd8SMatthew G Knepley @*/ 434931823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 435031823bd8SMatthew G Knepley { 435131823bd8SMatthew G Knepley PetscErrorCode ierr; 435231823bd8SMatthew G Knepley 435331823bd8SMatthew G Knepley PetscFunctionBegin; 435431823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 435531823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 435631823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 435731823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4358bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 435931823bd8SMatthew G Knepley snes->pc = pc; 436031823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 436131823bd8SMatthew G Knepley PetscFunctionReturn(0); 436231823bd8SMatthew G Knepley } 436331823bd8SMatthew G Knepley 436431823bd8SMatthew G Knepley #undef __FUNCT__ 436531823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 436631823bd8SMatthew G Knepley /*@ 4367fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 436831823bd8SMatthew G Knepley 436931823bd8SMatthew G Knepley Not Collective 437031823bd8SMatthew G Knepley 437131823bd8SMatthew G Knepley Input Parameter: 437231823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 437331823bd8SMatthew G Knepley 437431823bd8SMatthew G Knepley Output Parameter: 437531823bd8SMatthew G Knepley . pc - preconditioner context 437631823bd8SMatthew G Knepley 437731823bd8SMatthew G Knepley Level: developer 437831823bd8SMatthew G Knepley 437931823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 438031823bd8SMatthew G Knepley .seealso: SNESSetPC() 438131823bd8SMatthew G Knepley @*/ 438231823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 438331823bd8SMatthew G Knepley { 438431823bd8SMatthew G Knepley PetscErrorCode ierr; 4385a64e098fSPeter Brune const char *optionsprefix; 438631823bd8SMatthew G Knepley 438731823bd8SMatthew G Knepley PetscFunctionBegin; 438831823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 438931823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 439031823bd8SMatthew G Knepley if (!snes->pc) { 439131823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm,&snes->pc);CHKERRQ(ierr); 43924a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr); 439331823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes,snes->pc);CHKERRQ(ierr); 4394a64e098fSPeter Brune ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr); 4395a64e098fSPeter Brune ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr); 4396a64e098fSPeter Brune ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr); 439731823bd8SMatthew G Knepley } 439831823bd8SMatthew G Knepley *pc = snes->pc; 439931823bd8SMatthew G Knepley PetscFunctionReturn(0); 440031823bd8SMatthew G Knepley } 440131823bd8SMatthew G Knepley 44029e764e56SPeter Brune #undef __FUNCT__ 4403f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch" 44049e764e56SPeter Brune /*@ 44058141a3b9SPeter Brune SNESSetSNESLineSearch - Sets the linesearch on the SNES instance. 44069e764e56SPeter Brune 44079e764e56SPeter Brune Collective on SNES 44089e764e56SPeter Brune 44099e764e56SPeter Brune Input Parameters: 44109e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 44119e764e56SPeter Brune - linesearch - the linesearch object 44129e764e56SPeter Brune 44139e764e56SPeter Brune Notes: 4414f1c6b773SPeter Brune Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example, 44159e764e56SPeter Brune to configure it using the API). 44169e764e56SPeter Brune 44179e764e56SPeter Brune Level: developer 44189e764e56SPeter Brune 44199e764e56SPeter Brune .keywords: SNES, set, linesearch 4420f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch() 44219e764e56SPeter Brune @*/ 4422f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch) 44239e764e56SPeter Brune { 44249e764e56SPeter Brune PetscErrorCode ierr; 44259e764e56SPeter Brune 44269e764e56SPeter Brune PetscFunctionBegin; 44279e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4428f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 44299e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 44309e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 4431f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 44329e764e56SPeter Brune snes->linesearch = linesearch; 44339e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 44349e764e56SPeter Brune PetscFunctionReturn(0); 44359e764e56SPeter Brune } 44369e764e56SPeter Brune 44379e764e56SPeter Brune #undef __FUNCT__ 4438f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch" 4439ea5d4fccSPeter Brune /*@C 44408141a3b9SPeter Brune SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 44418141a3b9SPeter Brune or creates a default line search instance associated with the SNES and returns it. 44429e764e56SPeter Brune 44439e764e56SPeter Brune Not Collective 44449e764e56SPeter Brune 44459e764e56SPeter Brune Input Parameter: 44469e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 44479e764e56SPeter Brune 44489e764e56SPeter Brune Output Parameter: 44499e764e56SPeter Brune . linesearch - linesearch context 44509e764e56SPeter Brune 44519e764e56SPeter Brune Level: developer 44529e764e56SPeter Brune 44539e764e56SPeter Brune .keywords: SNES, get, linesearch 4454f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch() 44559e764e56SPeter Brune @*/ 4456f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch) 44579e764e56SPeter Brune { 44589e764e56SPeter Brune PetscErrorCode ierr; 44599e764e56SPeter Brune const char *optionsprefix; 44609e764e56SPeter Brune 44619e764e56SPeter Brune PetscFunctionBegin; 44629e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 44639e764e56SPeter Brune PetscValidPointer(linesearch, 2); 44649e764e56SPeter Brune if (!snes->linesearch) { 44659e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 4466f1c6b773SPeter Brune ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr); 4467f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 4468b1dca40bSPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 44699e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 44709e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 44719e764e56SPeter Brune } 44729e764e56SPeter Brune *linesearch = snes->linesearch; 44739e764e56SPeter Brune PetscFunctionReturn(0); 44749e764e56SPeter Brune } 44759e764e56SPeter Brune 447669b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4477c6db04a5SJed Brown #include <mex.h> 447869b4f73cSBarry Smith 44798f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 44808f6e6473SBarry Smith 44810807856dSBarry Smith #undef __FUNCT__ 44820807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 44830807856dSBarry Smith /* 44840807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 44850807856dSBarry Smith SNESSetFunctionMatlab(). 44860807856dSBarry Smith 44870807856dSBarry Smith Collective on SNES 44880807856dSBarry Smith 44890807856dSBarry Smith Input Parameters: 44900807856dSBarry Smith + snes - the SNES context 44910807856dSBarry Smith - x - input vector 44920807856dSBarry Smith 44930807856dSBarry Smith Output Parameter: 44940807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 44950807856dSBarry Smith 44960807856dSBarry Smith Notes: 44970807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 44980807856dSBarry Smith implementations, so most users would not generally call this routine 44990807856dSBarry Smith themselves. 45000807856dSBarry Smith 45010807856dSBarry Smith Level: developer 45020807856dSBarry Smith 45030807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 45040807856dSBarry Smith 45050807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 450661b2408cSBarry Smith */ 45077087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 45080807856dSBarry Smith { 4509e650e774SBarry Smith PetscErrorCode ierr; 45108f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 45118f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 45128f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 451391621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 4514e650e774SBarry Smith 45150807856dSBarry Smith PetscFunctionBegin; 45160807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 45170807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 45180807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 45190807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 45200807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 45210807856dSBarry Smith 45220807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 4523e650e774SBarry Smith 452491621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4525e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4526e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 452791621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 452891621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 452991621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 45308f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 45318f6e6473SBarry Smith prhs[4] = sctx->ctx; 4532b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 4533e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4534e650e774SBarry Smith mxDestroyArray(prhs[0]); 4535e650e774SBarry Smith mxDestroyArray(prhs[1]); 4536e650e774SBarry Smith mxDestroyArray(prhs[2]); 45378f6e6473SBarry Smith mxDestroyArray(prhs[3]); 4538e650e774SBarry Smith mxDestroyArray(plhs[0]); 45390807856dSBarry Smith PetscFunctionReturn(0); 45400807856dSBarry Smith } 45410807856dSBarry Smith 45420807856dSBarry Smith 45430807856dSBarry Smith #undef __FUNCT__ 45440807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 454561b2408cSBarry Smith /* 45460807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 45470807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4548e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 45490807856dSBarry Smith 45500807856dSBarry Smith Logically Collective on SNES 45510807856dSBarry Smith 45520807856dSBarry Smith Input Parameters: 45530807856dSBarry Smith + snes - the SNES context 45540807856dSBarry Smith . r - vector to store function value 45550807856dSBarry Smith - func - function evaluation routine 45560807856dSBarry Smith 45570807856dSBarry Smith Calling sequence of func: 455861b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 45590807856dSBarry Smith 45600807856dSBarry Smith 45610807856dSBarry Smith Notes: 45620807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 45630807856dSBarry Smith $ f'(x) x = -f(x), 45640807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 45650807856dSBarry Smith 45660807856dSBarry Smith Level: beginner 45670807856dSBarry Smith 45680807856dSBarry Smith .keywords: SNES, nonlinear, set, function 45690807856dSBarry Smith 45700807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 457161b2408cSBarry Smith */ 45727087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 45730807856dSBarry Smith { 45740807856dSBarry Smith PetscErrorCode ierr; 45758f6e6473SBarry Smith SNESMatlabContext *sctx; 45760807856dSBarry Smith 45770807856dSBarry Smith PetscFunctionBegin; 45788f6e6473SBarry Smith /* currently sctx is memory bleed */ 45798f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 45808f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 45818f6e6473SBarry Smith /* 45828f6e6473SBarry Smith This should work, but it doesn't 45838f6e6473SBarry Smith sctx->ctx = ctx; 45848f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 45858f6e6473SBarry Smith */ 45868f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 45878f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 45880807856dSBarry Smith PetscFunctionReturn(0); 45890807856dSBarry Smith } 459069b4f73cSBarry Smith 459161b2408cSBarry Smith #undef __FUNCT__ 459261b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 459361b2408cSBarry Smith /* 459461b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 459561b2408cSBarry Smith SNESSetJacobianMatlab(). 459661b2408cSBarry Smith 459761b2408cSBarry Smith Collective on SNES 459861b2408cSBarry Smith 459961b2408cSBarry Smith Input Parameters: 460061b2408cSBarry Smith + snes - the SNES context 460161b2408cSBarry Smith . x - input vector 460261b2408cSBarry Smith . A, B - the matrices 460361b2408cSBarry Smith - ctx - user context 460461b2408cSBarry Smith 460561b2408cSBarry Smith Output Parameter: 460661b2408cSBarry Smith . flag - structure of the matrix 460761b2408cSBarry Smith 460861b2408cSBarry Smith Level: developer 460961b2408cSBarry Smith 461061b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 461161b2408cSBarry Smith 461261b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 461361b2408cSBarry Smith @*/ 46147087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 461561b2408cSBarry Smith { 461661b2408cSBarry Smith PetscErrorCode ierr; 461761b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 461861b2408cSBarry Smith int nlhs = 2,nrhs = 6; 461961b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 462061b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 462161b2408cSBarry Smith 462261b2408cSBarry Smith PetscFunctionBegin; 462361b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 462461b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 462561b2408cSBarry Smith 462661b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 462761b2408cSBarry Smith 462861b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 462961b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 463061b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 463161b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 463261b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 463361b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 463461b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 463561b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 463661b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 463761b2408cSBarry Smith prhs[5] = sctx->ctx; 4638b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 463961b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 464061b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 464161b2408cSBarry Smith mxDestroyArray(prhs[0]); 464261b2408cSBarry Smith mxDestroyArray(prhs[1]); 464361b2408cSBarry Smith mxDestroyArray(prhs[2]); 464461b2408cSBarry Smith mxDestroyArray(prhs[3]); 464561b2408cSBarry Smith mxDestroyArray(prhs[4]); 464661b2408cSBarry Smith mxDestroyArray(plhs[0]); 464761b2408cSBarry Smith mxDestroyArray(plhs[1]); 464861b2408cSBarry Smith PetscFunctionReturn(0); 464961b2408cSBarry Smith } 465061b2408cSBarry Smith 465161b2408cSBarry Smith 465261b2408cSBarry Smith #undef __FUNCT__ 465361b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 465461b2408cSBarry Smith /* 465561b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 465661b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4657e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 465861b2408cSBarry Smith 465961b2408cSBarry Smith Logically Collective on SNES 466061b2408cSBarry Smith 466161b2408cSBarry Smith Input Parameters: 466261b2408cSBarry Smith + snes - the SNES context 466361b2408cSBarry Smith . A,B - Jacobian matrices 466461b2408cSBarry Smith . func - function evaluation routine 466561b2408cSBarry Smith - ctx - user context 466661b2408cSBarry Smith 466761b2408cSBarry Smith Calling sequence of func: 466861b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 466961b2408cSBarry Smith 467061b2408cSBarry Smith 467161b2408cSBarry Smith Level: developer 467261b2408cSBarry Smith 467361b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 467461b2408cSBarry Smith 467561b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 467661b2408cSBarry Smith */ 46777087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 467861b2408cSBarry Smith { 467961b2408cSBarry Smith PetscErrorCode ierr; 468061b2408cSBarry Smith SNESMatlabContext *sctx; 468161b2408cSBarry Smith 468261b2408cSBarry Smith PetscFunctionBegin; 468361b2408cSBarry Smith /* currently sctx is memory bleed */ 468461b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 468561b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 468661b2408cSBarry Smith /* 468761b2408cSBarry Smith This should work, but it doesn't 468861b2408cSBarry Smith sctx->ctx = ctx; 468961b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 469061b2408cSBarry Smith */ 469161b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 469261b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 469361b2408cSBarry Smith PetscFunctionReturn(0); 469461b2408cSBarry Smith } 469569b4f73cSBarry Smith 4696f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4697f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4698f9eb7ae2SShri Abhyankar /* 4699f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4700f9eb7ae2SShri Abhyankar 4701f9eb7ae2SShri Abhyankar Collective on SNES 4702f9eb7ae2SShri Abhyankar 4703f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4704f9eb7ae2SShri Abhyankar @*/ 47057087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4706f9eb7ae2SShri Abhyankar { 4707f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 470848f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4709f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4710f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4711f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4712f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4713f9eb7ae2SShri Abhyankar 4714f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4715f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4716f9eb7ae2SShri Abhyankar 4717f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4718f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4719f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4720f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4721f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4722f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4723f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4724f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4725f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4726f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4727f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4728f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4729f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4730f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4731f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4732f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4733f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4734f9eb7ae2SShri Abhyankar } 4735f9eb7ae2SShri Abhyankar 4736f9eb7ae2SShri Abhyankar 4737f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4738f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4739f9eb7ae2SShri Abhyankar /* 4740e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4741f9eb7ae2SShri Abhyankar 4742f9eb7ae2SShri Abhyankar Level: developer 4743f9eb7ae2SShri Abhyankar 4744f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4745f9eb7ae2SShri Abhyankar 4746f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4747f9eb7ae2SShri Abhyankar */ 47487087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4749f9eb7ae2SShri Abhyankar { 4750f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4751f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4752f9eb7ae2SShri Abhyankar 4753f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4754f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4755f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4756f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4757f9eb7ae2SShri Abhyankar /* 4758f9eb7ae2SShri Abhyankar This should work, but it doesn't 4759f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4760f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4761f9eb7ae2SShri Abhyankar */ 4762f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4763f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4764f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4765f9eb7ae2SShri Abhyankar } 4766f9eb7ae2SShri Abhyankar 476769b4f73cSBarry Smith #endif 4768