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) { 3986cab3a1bSJed Brown Mat J,B; 399*06f20277SJed Brown void *functx; 4006cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 4016cab3a1bSJed Brown if (snes->mf_operator) { 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 } else { 4066cab3a1bSJed Brown J = B; 4076cab3a1bSJed Brown ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr); 4086cab3a1bSJed Brown } 409*06f20277SJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 410*06f20277SJed Brown ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,functx);CHKERRQ(ierr); 4116cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 4126cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 4136cab3a1bSJed Brown } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) { 4146cab3a1bSJed Brown Mat J; 4156cab3a1bSJed Brown void *functx; 4166cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4176cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4186cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4196cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 4206cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr); 4216cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 422caa4e7f2SJed Brown } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 4236cab3a1bSJed Brown Mat J,B; 4246cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4256cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4266cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4276cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 428*06f20277SJed Brown /* sdm->computejacobian was already set to reach here */ 429*06f20277SJed Brown ierr = SNESSetJacobian(snes,J,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 4306cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 4316cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 432caa4e7f2SJed Brown } else if (!snes->jacobian_pre) { 4336cab3a1bSJed Brown Mat J,B; 4346cab3a1bSJed Brown J = snes->jacobian; 4356cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 4366cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 4376cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 4386cab3a1bSJed Brown } 439caa4e7f2SJed Brown { 44060a3618bSJed Brown PetscBool flg = PETSC_FALSE; 441caa4e7f2SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_kspcompute",&flg,PETSC_NULL);CHKERRQ(ierr); 442caa4e7f2SJed Brown if (flg) { /* Plan to transition to this model */ 443caa4e7f2SJed Brown KSP ksp; 444caa4e7f2SJed Brown ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 445caa4e7f2SJed Brown ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr); 446dfe15315SJed Brown ierr = DMCoarsenHookAdd(snes->dm,PETSC_NULL,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 447caa4e7f2SJed Brown } 448caa4e7f2SJed Brown } 4496cab3a1bSJed Brown PetscFunctionReturn(0); 4506cab3a1bSJed Brown } 4516cab3a1bSJed Brown 4526cab3a1bSJed Brown #undef __FUNCT__ 4534a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions" 4549b94acceSBarry Smith /*@ 45594b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 4569b94acceSBarry Smith 457c7afd0dbSLois Curfman McInnes Collective on SNES 458c7afd0dbSLois Curfman McInnes 4599b94acceSBarry Smith Input Parameter: 4609b94acceSBarry Smith . snes - the SNES context 4619b94acceSBarry Smith 46236851e7fSLois Curfman McInnes Options Database Keys: 463ea630c6eSPeter Brune + -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas 46482738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 46582738288SBarry Smith of the change in the solution between steps 46670441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 467b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 468b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 469b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 4704839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 471ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 472a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 473e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 474b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 4752492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 47682738288SBarry Smith solver; hence iterations will continue until max_it 4771fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 47882738288SBarry Smith of convergence test 479e8105e01SRichard Katz . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 480e8105e01SRichard Katz filename given prints to stdout 481a6570f20SBarry Smith . -snes_monitor_solution - plots solution at each iteration 482a6570f20SBarry Smith . -snes_monitor_residual - plots residual (not its norm) at each iteration 483a6570f20SBarry Smith . -snes_monitor_solution_update - plots update to solution at each iteration 484a6570f20SBarry Smith . -snes_monitor_draw - plots residual norm at each iteration 485e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 4865968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 487fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 48882738288SBarry Smith 48982738288SBarry Smith Options Database for Eisenstat-Walker method: 490fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 4914b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 49236851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 49336851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 49436851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 49536851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 49636851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 49736851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 49882738288SBarry Smith 49911ca99fdSLois Curfman McInnes Notes: 50011ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 5010598bfebSBarry Smith the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>. 50283e2fdc7SBarry Smith 50336851e7fSLois Curfman McInnes Level: beginner 50436851e7fSLois Curfman McInnes 5059b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 5069b94acceSBarry Smith 50769ed319cSSatish Balay .seealso: SNESSetOptionsPrefix() 5089b94acceSBarry Smith @*/ 5097087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 5109b94acceSBarry Smith { 511872b6db9SPeter Brune PetscBool flg,mf,mf_operator,pcset; 512efd51863SBarry Smith PetscInt i,indx,lag,mf_version,grids; 513aa3661deSLisandro Dalcin MatStructure matflag; 51485385478SLisandro Dalcin const char *deft = SNESLS; 51585385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 51685385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 517e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 518649052a6SBarry Smith PetscViewer monviewer; 51985385478SLisandro Dalcin PetscErrorCode ierr; 520a64e098fSPeter Brune const char *optionsprefix; 5219b94acceSBarry Smith 5223a40ed3dSBarry Smith PetscFunctionBegin; 5230700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 524ca161407SBarry Smith 525186905e3SBarry Smith if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 5263194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 5277adad957SLisandro Dalcin if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; } 528b0a32e0cSBarry Smith ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 529d64ed03dSBarry Smith if (flg) { 530186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 5317adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 532186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 533d64ed03dSBarry Smith } 53490d69ab7SBarry Smith /* not used here, but called so will go into help messaage */ 535909c8a9fSBarry Smith ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 53693c39befSBarry Smith 537c60f73f4SPeter Brune ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr); 53857034d6fSHong Zhang ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 539186905e3SBarry Smith 54057034d6fSHong Zhang ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 541b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 542b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 54324254dc1SJed Brown ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 544ddf469c8SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr); 545acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr); 54685385478SLisandro Dalcin 547a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 548a8054027SBarry Smith if (flg) { 549a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 550a8054027SBarry Smith } 551e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 552e35cf81dSBarry Smith if (flg) { 553e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 554e35cf81dSBarry Smith } 555efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 556efd51863SBarry Smith if (flg) { 557efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 558efd51863SBarry Smith } 559a8054027SBarry Smith 56085385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 56185385478SLisandro Dalcin if (flg) { 56285385478SLisandro Dalcin switch (indx) { 5637f7931b9SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 5647f7931b9SBarry Smith case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 56585385478SLisandro Dalcin } 56685385478SLisandro Dalcin } 56785385478SLisandro Dalcin 568acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr); 569186905e3SBarry Smith 570fdacfa88SPeter Brune ierr = PetscOptionsEList("-snes_norm_type","SNES Norm type","SNESSetNormType",SNESNormTypes,5,"function",&indx,&flg);CHKERRQ(ierr); 571fdacfa88SPeter Brune if (flg) { ierr = SNESSetNormType(snes,(SNESNormType)indx);CHKERRQ(ierr); } 572fdacfa88SPeter Brune 57385385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 57485385478SLisandro Dalcin 575acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 576186905e3SBarry Smith 577fa9f3622SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 578fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 579fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 580fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 581fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 582fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 583fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 584186905e3SBarry Smith 58590d69ab7SBarry Smith flg = PETSC_FALSE; 586acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 587a6570f20SBarry Smith if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 588eabae89aSBarry Smith 589a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 590e8105e01SRichard Katz if (flg) { 591649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 592649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 593e8105e01SRichard Katz } 594eabae89aSBarry Smith 595b271bb04SBarry Smith ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 596b271bb04SBarry Smith if (flg) { 597b271bb04SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 598b271bb04SBarry Smith } 599b271bb04SBarry Smith 600a6570f20SBarry Smith ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 601eabae89aSBarry Smith if (flg) { 602649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 603f1bef1bcSMatthew Knepley ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 604e8105e01SRichard Katz } 605eabae89aSBarry Smith 606a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 607eabae89aSBarry Smith if (flg) { 608649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 609649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 610eabae89aSBarry Smith } 611eabae89aSBarry Smith 6125180491cSLisandro Dalcin ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 6135180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 6145180491cSLisandro Dalcin 61590d69ab7SBarry Smith flg = PETSC_FALSE; 616acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 617a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 61890d69ab7SBarry Smith flg = PETSC_FALSE; 619acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 620a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 62190d69ab7SBarry Smith flg = PETSC_FALSE; 622acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 623a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 62490d69ab7SBarry Smith flg = PETSC_FALSE; 625acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 626a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 62790d69ab7SBarry Smith flg = PETSC_FALSE; 628acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 629b271bb04SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 630e24b481bSBarry Smith 63190d69ab7SBarry Smith flg = PETSC_FALSE; 632acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 6334b27c08aSLois Curfman McInnes if (flg) { 6346cab3a1bSJed Brown void *functx; 6356cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 6366cab3a1bSJed Brown ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr); 637ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 6389b94acceSBarry Smith } 639639f9d9dSBarry Smith 640aa3661deSLisandro Dalcin mf = mf_operator = PETSC_FALSE; 641aa3661deSLisandro Dalcin flg = PETSC_FALSE; 642acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr); 643a8248277SBarry Smith if (flg && mf_operator) { 644a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 645a8248277SBarry Smith mf = PETSC_TRUE; 646a8248277SBarry Smith } 647aa3661deSLisandro Dalcin flg = PETSC_FALSE; 648acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr); 649aa3661deSLisandro Dalcin if (!flg && mf_operator) mf = PETSC_TRUE; 650aa3661deSLisandro Dalcin mf_version = 1; 651aa3661deSLisandro Dalcin ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr); 652aa3661deSLisandro Dalcin 653d28543b3SPeter Brune 65489b92e6fSPeter Brune /* GS Options */ 65589b92e6fSPeter Brune ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr); 65689b92e6fSPeter Brune 65776b2cf59SMatthew Knepley for(i = 0; i < numberofsetfromoptions; i++) { 65876b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 65976b2cf59SMatthew Knepley } 66076b2cf59SMatthew Knepley 661e7788613SBarry Smith if (snes->ops->setfromoptions) { 662e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 663639f9d9dSBarry Smith } 6645d973c19SBarry Smith 6655d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 6665d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 667b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 6684bbc92c1SBarry Smith 669aa3661deSLisandro Dalcin if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 6701cee3971SBarry Smith 6711cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 672aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 673aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 67485385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 67593993e2dSLois Curfman McInnes 6769e764e56SPeter Brune if (!snes->linesearch) { 677f1c6b773SPeter Brune ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 6789e764e56SPeter Brune } 679f1c6b773SPeter Brune ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr); 6809e764e56SPeter Brune 68151e86f29SPeter Brune /* if someone has set the SNES PC type, create it. */ 68251e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 68351e86f29SPeter Brune ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 68451e86f29SPeter Brune if (pcset && (!snes->pc)) { 68551e86f29SPeter Brune ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr); 68651e86f29SPeter Brune } 6873a40ed3dSBarry Smith PetscFunctionReturn(0); 6889b94acceSBarry Smith } 6899b94acceSBarry Smith 690d25893d9SBarry Smith #undef __FUNCT__ 691d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 692d25893d9SBarry Smith /*@ 693d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 694d25893d9SBarry Smith the nonlinear solvers. 695d25893d9SBarry Smith 696d25893d9SBarry Smith Logically Collective on SNES 697d25893d9SBarry Smith 698d25893d9SBarry Smith Input Parameters: 699d25893d9SBarry Smith + snes - the SNES context 700d25893d9SBarry Smith . compute - function to compute the context 701d25893d9SBarry Smith - destroy - function to destroy the context 702d25893d9SBarry Smith 703d25893d9SBarry Smith Level: intermediate 704d25893d9SBarry Smith 705d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 706d25893d9SBarry Smith 707d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 708d25893d9SBarry Smith @*/ 709d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 710d25893d9SBarry Smith { 711d25893d9SBarry Smith PetscFunctionBegin; 712d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 713d25893d9SBarry Smith snes->ops->usercompute = compute; 714d25893d9SBarry Smith snes->ops->userdestroy = destroy; 715d25893d9SBarry Smith PetscFunctionReturn(0); 716d25893d9SBarry Smith } 717a847f771SSatish Balay 7184a2ae208SSatish Balay #undef __FUNCT__ 7194a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 720b07ff414SBarry Smith /*@ 7219b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 7229b94acceSBarry Smith the nonlinear solvers. 7239b94acceSBarry Smith 7243f9fe445SBarry Smith Logically Collective on SNES 725fee21e36SBarry Smith 726c7afd0dbSLois Curfman McInnes Input Parameters: 727c7afd0dbSLois Curfman McInnes + snes - the SNES context 728c7afd0dbSLois Curfman McInnes - usrP - optional user context 729c7afd0dbSLois Curfman McInnes 73036851e7fSLois Curfman McInnes Level: intermediate 73136851e7fSLois Curfman McInnes 7329b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 7339b94acceSBarry Smith 734ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext() 7359b94acceSBarry Smith @*/ 7367087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 7379b94acceSBarry Smith { 7381b2093e4SBarry Smith PetscErrorCode ierr; 739b07ff414SBarry Smith KSP ksp; 7401b2093e4SBarry Smith 7413a40ed3dSBarry Smith PetscFunctionBegin; 7420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 743b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 744b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 7459b94acceSBarry Smith snes->user = usrP; 7463a40ed3dSBarry Smith PetscFunctionReturn(0); 7479b94acceSBarry Smith } 74874679c65SBarry Smith 7494a2ae208SSatish Balay #undef __FUNCT__ 7504a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 751b07ff414SBarry Smith /*@ 7529b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 7539b94acceSBarry Smith nonlinear solvers. 7549b94acceSBarry Smith 755c7afd0dbSLois Curfman McInnes Not Collective 756c7afd0dbSLois Curfman McInnes 7579b94acceSBarry Smith Input Parameter: 7589b94acceSBarry Smith . snes - SNES context 7599b94acceSBarry Smith 7609b94acceSBarry Smith Output Parameter: 7619b94acceSBarry Smith . usrP - user context 7629b94acceSBarry Smith 76336851e7fSLois Curfman McInnes Level: intermediate 76436851e7fSLois Curfman McInnes 7659b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 7669b94acceSBarry Smith 7679b94acceSBarry Smith .seealso: SNESSetApplicationContext() 7689b94acceSBarry Smith @*/ 769e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 7709b94acceSBarry Smith { 7713a40ed3dSBarry Smith PetscFunctionBegin; 7720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 773e71120c6SJed Brown *(void**)usrP = snes->user; 7743a40ed3dSBarry Smith PetscFunctionReturn(0); 7759b94acceSBarry Smith } 77674679c65SBarry Smith 7774a2ae208SSatish Balay #undef __FUNCT__ 7784a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 7799b94acceSBarry Smith /*@ 780c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 781c8228a4eSBarry Smith at this time. 7829b94acceSBarry Smith 783c7afd0dbSLois Curfman McInnes Not Collective 784c7afd0dbSLois Curfman McInnes 7859b94acceSBarry Smith Input Parameter: 7869b94acceSBarry Smith . snes - SNES context 7879b94acceSBarry Smith 7889b94acceSBarry Smith Output Parameter: 7899b94acceSBarry Smith . iter - iteration number 7909b94acceSBarry Smith 791c8228a4eSBarry Smith Notes: 792c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 793c8228a4eSBarry Smith 794c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 79508405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 79608405cd6SLois Curfman McInnes .vb 79708405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 79808405cd6SLois Curfman McInnes if (!(it % 2)) { 79908405cd6SLois Curfman McInnes [compute Jacobian here] 80008405cd6SLois Curfman McInnes } 80108405cd6SLois Curfman McInnes .ve 802c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 80308405cd6SLois Curfman McInnes recomputed every second SNES iteration. 804c8228a4eSBarry Smith 80536851e7fSLois Curfman McInnes Level: intermediate 80636851e7fSLois Curfman McInnes 8072b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 8082b668275SBarry Smith 809b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 8109b94acceSBarry Smith @*/ 8117087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 8129b94acceSBarry Smith { 8133a40ed3dSBarry Smith PetscFunctionBegin; 8140700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8154482741eSBarry Smith PetscValidIntPointer(iter,2); 8169b94acceSBarry Smith *iter = snes->iter; 8173a40ed3dSBarry Smith PetscFunctionReturn(0); 8189b94acceSBarry Smith } 81974679c65SBarry Smith 8204a2ae208SSatish Balay #undef __FUNCT__ 821360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber" 822360c497dSPeter Brune /*@ 823360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 824360c497dSPeter Brune 825360c497dSPeter Brune Not Collective 826360c497dSPeter Brune 827360c497dSPeter Brune Input Parameter: 828360c497dSPeter Brune . snes - SNES context 829360c497dSPeter Brune . iter - iteration number 830360c497dSPeter Brune 831360c497dSPeter Brune Level: developer 832360c497dSPeter Brune 833360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number, 834360c497dSPeter Brune 835360c497dSPeter Brune .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 836360c497dSPeter Brune @*/ 837360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 838360c497dSPeter Brune { 839360c497dSPeter Brune PetscErrorCode ierr; 840360c497dSPeter Brune 841360c497dSPeter Brune PetscFunctionBegin; 842360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 843360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 844360c497dSPeter Brune snes->iter = iter; 845360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 846360c497dSPeter Brune PetscFunctionReturn(0); 847360c497dSPeter Brune } 848360c497dSPeter Brune 849360c497dSPeter Brune #undef __FUNCT__ 8504a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 8519b94acceSBarry Smith /*@ 8529b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 8539b94acceSBarry Smith with SNESSSetFunction(). 8549b94acceSBarry Smith 855c7afd0dbSLois Curfman McInnes Collective on SNES 856c7afd0dbSLois Curfman McInnes 8579b94acceSBarry Smith Input Parameter: 8589b94acceSBarry Smith . snes - SNES context 8599b94acceSBarry Smith 8609b94acceSBarry Smith Output Parameter: 8619b94acceSBarry Smith . fnorm - 2-norm of function 8629b94acceSBarry Smith 86336851e7fSLois Curfman McInnes Level: intermediate 86436851e7fSLois Curfman McInnes 8659b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 866a86d99e1SLois Curfman McInnes 867b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 8689b94acceSBarry Smith @*/ 8697087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 8709b94acceSBarry Smith { 8713a40ed3dSBarry Smith PetscFunctionBegin; 8720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8734482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 8749b94acceSBarry Smith *fnorm = snes->norm; 8753a40ed3dSBarry Smith PetscFunctionReturn(0); 8769b94acceSBarry Smith } 87774679c65SBarry Smith 878360c497dSPeter Brune 879360c497dSPeter Brune #undef __FUNCT__ 880360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm" 881360c497dSPeter Brune /*@ 882360c497dSPeter Brune SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm(). 883360c497dSPeter Brune 884360c497dSPeter Brune Collective on SNES 885360c497dSPeter Brune 886360c497dSPeter Brune Input Parameter: 887360c497dSPeter Brune . snes - SNES context 888360c497dSPeter Brune . fnorm - 2-norm of function 889360c497dSPeter Brune 890360c497dSPeter Brune Level: developer 891360c497dSPeter Brune 892360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm 893360c497dSPeter Brune 894360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm(). 895360c497dSPeter Brune @*/ 896360c497dSPeter Brune PetscErrorCode SNESSetFunctionNorm(SNES snes,PetscReal fnorm) 897360c497dSPeter Brune { 898360c497dSPeter Brune 899360c497dSPeter Brune PetscErrorCode ierr; 900360c497dSPeter Brune 901360c497dSPeter Brune PetscFunctionBegin; 902360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 903360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 904360c497dSPeter Brune snes->norm = fnorm; 905360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 906360c497dSPeter Brune PetscFunctionReturn(0); 907360c497dSPeter Brune } 908360c497dSPeter Brune 9094a2ae208SSatish Balay #undef __FUNCT__ 910b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 9119b94acceSBarry Smith /*@ 912b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 9139b94acceSBarry Smith attempted by the nonlinear solver. 9149b94acceSBarry Smith 915c7afd0dbSLois Curfman McInnes Not Collective 916c7afd0dbSLois Curfman McInnes 9179b94acceSBarry Smith Input Parameter: 9189b94acceSBarry Smith . snes - SNES context 9199b94acceSBarry Smith 9209b94acceSBarry Smith Output Parameter: 9219b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 9229b94acceSBarry Smith 923c96a6f78SLois Curfman McInnes Notes: 924c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 925c96a6f78SLois Curfman McInnes 92636851e7fSLois Curfman McInnes Level: intermediate 92736851e7fSLois Curfman McInnes 9289b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 92958ebbce7SBarry Smith 930e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 93158ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 9329b94acceSBarry Smith @*/ 9337087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 9349b94acceSBarry Smith { 9353a40ed3dSBarry Smith PetscFunctionBegin; 9360700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9374482741eSBarry Smith PetscValidIntPointer(nfails,2); 93850ffb88aSMatthew Knepley *nfails = snes->numFailures; 93950ffb88aSMatthew Knepley PetscFunctionReturn(0); 94050ffb88aSMatthew Knepley } 94150ffb88aSMatthew Knepley 94250ffb88aSMatthew Knepley #undef __FUNCT__ 943b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 94450ffb88aSMatthew Knepley /*@ 945b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 94650ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 94750ffb88aSMatthew Knepley 94850ffb88aSMatthew Knepley Not Collective 94950ffb88aSMatthew Knepley 95050ffb88aSMatthew Knepley Input Parameters: 95150ffb88aSMatthew Knepley + snes - SNES context 95250ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 95350ffb88aSMatthew Knepley 95450ffb88aSMatthew Knepley Level: intermediate 95550ffb88aSMatthew Knepley 95650ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 95758ebbce7SBarry Smith 958e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 95958ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 96050ffb88aSMatthew Knepley @*/ 9617087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 96250ffb88aSMatthew Knepley { 96350ffb88aSMatthew Knepley PetscFunctionBegin; 9640700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 96550ffb88aSMatthew Knepley snes->maxFailures = maxFails; 96650ffb88aSMatthew Knepley PetscFunctionReturn(0); 96750ffb88aSMatthew Knepley } 96850ffb88aSMatthew Knepley 96950ffb88aSMatthew Knepley #undef __FUNCT__ 970b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 97150ffb88aSMatthew Knepley /*@ 972b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 97350ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 97450ffb88aSMatthew Knepley 97550ffb88aSMatthew Knepley Not Collective 97650ffb88aSMatthew Knepley 97750ffb88aSMatthew Knepley Input Parameter: 97850ffb88aSMatthew Knepley . snes - SNES context 97950ffb88aSMatthew Knepley 98050ffb88aSMatthew Knepley Output Parameter: 98150ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 98250ffb88aSMatthew Knepley 98350ffb88aSMatthew Knepley Level: intermediate 98450ffb88aSMatthew Knepley 98550ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 98658ebbce7SBarry Smith 987e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 98858ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 98958ebbce7SBarry Smith 99050ffb88aSMatthew Knepley @*/ 9917087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 99250ffb88aSMatthew Knepley { 99350ffb88aSMatthew Knepley PetscFunctionBegin; 9940700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9954482741eSBarry Smith PetscValidIntPointer(maxFails,2); 99650ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 9973a40ed3dSBarry Smith PetscFunctionReturn(0); 9989b94acceSBarry Smith } 999a847f771SSatish Balay 10004a2ae208SSatish Balay #undef __FUNCT__ 10012541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 10022541af92SBarry Smith /*@ 10032541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 10042541af92SBarry Smith done by SNES. 10052541af92SBarry Smith 10062541af92SBarry Smith Not Collective 10072541af92SBarry Smith 10082541af92SBarry Smith Input Parameter: 10092541af92SBarry Smith . snes - SNES context 10102541af92SBarry Smith 10112541af92SBarry Smith Output Parameter: 10122541af92SBarry Smith . nfuncs - number of evaluations 10132541af92SBarry Smith 10142541af92SBarry Smith Level: intermediate 10152541af92SBarry Smith 10162541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 101758ebbce7SBarry Smith 1018e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 10192541af92SBarry Smith @*/ 10207087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 10212541af92SBarry Smith { 10222541af92SBarry Smith PetscFunctionBegin; 10230700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10242541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 10252541af92SBarry Smith *nfuncs = snes->nfuncs; 10262541af92SBarry Smith PetscFunctionReturn(0); 10272541af92SBarry Smith } 10282541af92SBarry Smith 10292541af92SBarry Smith #undef __FUNCT__ 10303d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 10313d4c4710SBarry Smith /*@ 10323d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 10333d4c4710SBarry Smith linear solvers. 10343d4c4710SBarry Smith 10353d4c4710SBarry Smith Not Collective 10363d4c4710SBarry Smith 10373d4c4710SBarry Smith Input Parameter: 10383d4c4710SBarry Smith . snes - SNES context 10393d4c4710SBarry Smith 10403d4c4710SBarry Smith Output Parameter: 10413d4c4710SBarry Smith . nfails - number of failed solves 10423d4c4710SBarry Smith 10433d4c4710SBarry Smith Notes: 10443d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 10453d4c4710SBarry Smith 10463d4c4710SBarry Smith Level: intermediate 10473d4c4710SBarry Smith 10483d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 104958ebbce7SBarry Smith 1050e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 10513d4c4710SBarry Smith @*/ 10527087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 10533d4c4710SBarry Smith { 10543d4c4710SBarry Smith PetscFunctionBegin; 10550700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10563d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 10573d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 10583d4c4710SBarry Smith PetscFunctionReturn(0); 10593d4c4710SBarry Smith } 10603d4c4710SBarry Smith 10613d4c4710SBarry Smith #undef __FUNCT__ 10623d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 10633d4c4710SBarry Smith /*@ 10643d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 10653d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 10663d4c4710SBarry Smith 10673f9fe445SBarry Smith Logically Collective on SNES 10683d4c4710SBarry Smith 10693d4c4710SBarry Smith Input Parameters: 10703d4c4710SBarry Smith + snes - SNES context 10713d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 10723d4c4710SBarry Smith 10733d4c4710SBarry Smith Level: intermediate 10743d4c4710SBarry Smith 1075a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 10763d4c4710SBarry Smith 10773d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 10783d4c4710SBarry Smith 107958ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 10803d4c4710SBarry Smith @*/ 10817087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 10823d4c4710SBarry Smith { 10833d4c4710SBarry Smith PetscFunctionBegin; 10840700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1085c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 10863d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 10873d4c4710SBarry Smith PetscFunctionReturn(0); 10883d4c4710SBarry Smith } 10893d4c4710SBarry Smith 10903d4c4710SBarry Smith #undef __FUNCT__ 10913d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 10923d4c4710SBarry Smith /*@ 10933d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 10943d4c4710SBarry Smith are allowed before SNES terminates 10953d4c4710SBarry Smith 10963d4c4710SBarry Smith Not Collective 10973d4c4710SBarry Smith 10983d4c4710SBarry Smith Input Parameter: 10993d4c4710SBarry Smith . snes - SNES context 11003d4c4710SBarry Smith 11013d4c4710SBarry Smith Output Parameter: 11023d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 11033d4c4710SBarry Smith 11043d4c4710SBarry Smith Level: intermediate 11053d4c4710SBarry Smith 11063d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 11073d4c4710SBarry Smith 11083d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 11093d4c4710SBarry Smith 1110e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 11113d4c4710SBarry Smith @*/ 11127087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 11133d4c4710SBarry Smith { 11143d4c4710SBarry Smith PetscFunctionBegin; 11150700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11163d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 11173d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 11183d4c4710SBarry Smith PetscFunctionReturn(0); 11193d4c4710SBarry Smith } 11203d4c4710SBarry Smith 11213d4c4710SBarry Smith #undef __FUNCT__ 1122b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 1123c96a6f78SLois Curfman McInnes /*@ 1124b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1125c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1126c96a6f78SLois Curfman McInnes 1127c7afd0dbSLois Curfman McInnes Not Collective 1128c7afd0dbSLois Curfman McInnes 1129c96a6f78SLois Curfman McInnes Input Parameter: 1130c96a6f78SLois Curfman McInnes . snes - SNES context 1131c96a6f78SLois Curfman McInnes 1132c96a6f78SLois Curfman McInnes Output Parameter: 1133c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1134c96a6f78SLois Curfman McInnes 1135c96a6f78SLois Curfman McInnes Notes: 1136c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1137c96a6f78SLois Curfman McInnes 113836851e7fSLois Curfman McInnes Level: intermediate 113936851e7fSLois Curfman McInnes 1140c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 11412b668275SBarry Smith 11428c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 1143c96a6f78SLois Curfman McInnes @*/ 11447087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 1145c96a6f78SLois Curfman McInnes { 11463a40ed3dSBarry Smith PetscFunctionBegin; 11470700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11484482741eSBarry Smith PetscValidIntPointer(lits,2); 1149c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 11503a40ed3dSBarry Smith PetscFunctionReturn(0); 1151c96a6f78SLois Curfman McInnes } 1152c96a6f78SLois Curfman McInnes 11534a2ae208SSatish Balay #undef __FUNCT__ 115494b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 115552baeb72SSatish Balay /*@ 115694b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 11579b94acceSBarry Smith 115894b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 1159c7afd0dbSLois Curfman McInnes 11609b94acceSBarry Smith Input Parameter: 11619b94acceSBarry Smith . snes - the SNES context 11629b94acceSBarry Smith 11639b94acceSBarry Smith Output Parameter: 116494b7f48cSBarry Smith . ksp - the KSP context 11659b94acceSBarry Smith 11669b94acceSBarry Smith Notes: 116794b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 11689b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 11692999313aSBarry Smith PC contexts as well. 11709b94acceSBarry Smith 117136851e7fSLois Curfman McInnes Level: beginner 117236851e7fSLois Curfman McInnes 117394b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 11749b94acceSBarry Smith 11752999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 11769b94acceSBarry Smith @*/ 11777087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 11789b94acceSBarry Smith { 11791cee3971SBarry Smith PetscErrorCode ierr; 11801cee3971SBarry Smith 11813a40ed3dSBarry Smith PetscFunctionBegin; 11820700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11834482741eSBarry Smith PetscValidPointer(ksp,2); 11841cee3971SBarry Smith 11851cee3971SBarry Smith if (!snes->ksp) { 11861cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 11871cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 11881cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 11891cee3971SBarry Smith } 119094b7f48cSBarry Smith *ksp = snes->ksp; 11913a40ed3dSBarry Smith PetscFunctionReturn(0); 11929b94acceSBarry Smith } 119382bf6240SBarry Smith 11944a2ae208SSatish Balay #undef __FUNCT__ 11952999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 11962999313aSBarry Smith /*@ 11972999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 11982999313aSBarry Smith 11992999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 12002999313aSBarry Smith 12012999313aSBarry Smith Input Parameters: 12022999313aSBarry Smith + snes - the SNES context 12032999313aSBarry Smith - ksp - the KSP context 12042999313aSBarry Smith 12052999313aSBarry Smith Notes: 12062999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 12072999313aSBarry Smith so this routine is rarely needed. 12082999313aSBarry Smith 12092999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 12102999313aSBarry Smith decreased by one. 12112999313aSBarry Smith 12122999313aSBarry Smith Level: developer 12132999313aSBarry Smith 12142999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 12152999313aSBarry Smith 12162999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 12172999313aSBarry Smith @*/ 12187087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 12192999313aSBarry Smith { 12202999313aSBarry Smith PetscErrorCode ierr; 12212999313aSBarry Smith 12222999313aSBarry Smith PetscFunctionBegin; 12230700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12240700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 12252999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 12267dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1227906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 12282999313aSBarry Smith snes->ksp = ksp; 12292999313aSBarry Smith PetscFunctionReturn(0); 12302999313aSBarry Smith } 12312999313aSBarry Smith 12327adad957SLisandro Dalcin #if 0 12332999313aSBarry Smith #undef __FUNCT__ 12344a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 12356849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1236e24b481bSBarry Smith { 1237e24b481bSBarry Smith PetscFunctionBegin; 1238e24b481bSBarry Smith PetscFunctionReturn(0); 1239e24b481bSBarry Smith } 12407adad957SLisandro Dalcin #endif 1241e24b481bSBarry Smith 12429b94acceSBarry Smith /* -----------------------------------------------------------*/ 12434a2ae208SSatish Balay #undef __FUNCT__ 12444a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 124552baeb72SSatish Balay /*@ 12469b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 12479b94acceSBarry Smith 1248c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1249c7afd0dbSLois Curfman McInnes 1250c7afd0dbSLois Curfman McInnes Input Parameters: 1251906ed7ccSBarry Smith . comm - MPI communicator 12529b94acceSBarry Smith 12539b94acceSBarry Smith Output Parameter: 12549b94acceSBarry Smith . outsnes - the new SNES context 12559b94acceSBarry Smith 1256c7afd0dbSLois Curfman McInnes Options Database Keys: 1257c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1258c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1259c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1260c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1261c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1262c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1263c1f60f51SBarry Smith 126436851e7fSLois Curfman McInnes Level: beginner 126536851e7fSLois Curfman McInnes 12669b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 12679b94acceSBarry Smith 1268a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1269a8054027SBarry Smith 12709b94acceSBarry Smith @*/ 12717087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 12729b94acceSBarry Smith { 1273dfbe8321SBarry Smith PetscErrorCode ierr; 12749b94acceSBarry Smith SNES snes; 1275fa9f3622SBarry Smith SNESKSPEW *kctx; 127637fcc0dbSBarry Smith 12773a40ed3dSBarry Smith PetscFunctionBegin; 1278ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 12798ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 12808ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 12818ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 12828ba1e511SMatthew Knepley #endif 12838ba1e511SMatthew Knepley 12843194b578SJed Brown ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 12857adad957SLisandro Dalcin 128685385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 12872c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 128888976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 12899b94acceSBarry Smith snes->max_its = 50; 12909750a799SBarry Smith snes->max_funcs = 10000; 12919b94acceSBarry Smith snes->norm = 0.0; 1292fdacfa88SPeter Brune snes->normtype = SNES_NORM_FUNCTION; 1293b4874afaSBarry Smith snes->rtol = 1.e-8; 1294b4874afaSBarry Smith snes->ttol = 0.0; 129570441072SBarry Smith snes->abstol = 1.e-50; 1296c60f73f4SPeter Brune snes->stol = 1.e-8; 12974b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 12989b94acceSBarry Smith snes->nfuncs = 0; 129950ffb88aSMatthew Knepley snes->numFailures = 0; 130050ffb88aSMatthew Knepley snes->maxFailures = 1; 13017a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1302e35cf81dSBarry Smith snes->lagjacobian = 1; 1303a8054027SBarry Smith snes->lagpreconditioner = 1; 1304639f9d9dSBarry Smith snes->numbermonitors = 0; 13059b94acceSBarry Smith snes->data = 0; 13064dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1307186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 13086f24a144SLois Curfman McInnes snes->nwork = 0; 130958c9b817SLisandro Dalcin snes->work = 0; 131058c9b817SLisandro Dalcin snes->nvwork = 0; 131158c9b817SLisandro Dalcin snes->vwork = 0; 1312758f92a0SBarry Smith snes->conv_hist_len = 0; 1313758f92a0SBarry Smith snes->conv_hist_max = 0; 1314758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1315758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1316758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1317e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1318e4ed7901SPeter Brune snes->norm_init = 0.; 1319e4ed7901SPeter Brune snes->norm_init_set = PETSC_FALSE; 1320184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 132189b92e6fSPeter Brune snes->gssweeps = 1; 13229b94acceSBarry Smith 13233d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 13243d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 13253d4c4710SBarry Smith 13269b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 132738f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 13289b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 13299b94acceSBarry Smith kctx->version = 2; 13309b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 13319b94acceSBarry Smith this was too large for some test cases */ 133275567043SBarry Smith kctx->rtol_last = 0.0; 13339b94acceSBarry Smith kctx->rtol_max = .9; 13349b94acceSBarry Smith kctx->gamma = 1.0; 133562d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 133671f87433Sdalcinl kctx->alpha2 = kctx->alpha; 13379b94acceSBarry Smith kctx->threshold = .1; 133875567043SBarry Smith kctx->lresid_last = 0.0; 133975567043SBarry Smith kctx->norm_last = 0.0; 13409b94acceSBarry Smith 13419b94acceSBarry Smith *outsnes = snes; 13423a40ed3dSBarry Smith PetscFunctionReturn(0); 13439b94acceSBarry Smith } 13449b94acceSBarry Smith 13454a2ae208SSatish Balay #undef __FUNCT__ 13464a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 13479b94acceSBarry Smith /*@C 13489b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 13499b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 13509b94acceSBarry Smith equations. 13519b94acceSBarry Smith 13523f9fe445SBarry Smith Logically Collective on SNES 1353fee21e36SBarry Smith 1354c7afd0dbSLois Curfman McInnes Input Parameters: 1355c7afd0dbSLois Curfman McInnes + snes - the SNES context 1356c7afd0dbSLois Curfman McInnes . r - vector to store function value 1357de044059SHong Zhang . func - function evaluation routine 1358c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1359c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 13609b94acceSBarry Smith 1361c7afd0dbSLois Curfman McInnes Calling sequence of func: 13628d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1363c7afd0dbSLois Curfman McInnes 1364c586c404SJed Brown + snes - the SNES context 1365c586c404SJed Brown . x - state at which to evaluate residual 1366c586c404SJed Brown . f - vector to put residual 1367c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 13689b94acceSBarry Smith 13699b94acceSBarry Smith Notes: 13709b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 13719b94acceSBarry Smith $ f'(x) x = -f(x), 1372c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 13739b94acceSBarry Smith 137436851e7fSLois Curfman McInnes Level: beginner 137536851e7fSLois Curfman McInnes 13769b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 13779b94acceSBarry Smith 13788b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard() 13799b94acceSBarry Smith @*/ 13807087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 13819b94acceSBarry Smith { 138285385478SLisandro Dalcin PetscErrorCode ierr; 13836cab3a1bSJed Brown DM dm; 13846cab3a1bSJed Brown 13853a40ed3dSBarry Smith PetscFunctionBegin; 13860700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1387d2a683ecSLisandro Dalcin if (r) { 1388d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1389d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 139085385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 13916bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 139285385478SLisandro Dalcin snes->vec_func = r; 1393d2a683ecSLisandro Dalcin } 13946cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 13956cab3a1bSJed Brown ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr); 13963a40ed3dSBarry Smith PetscFunctionReturn(0); 13979b94acceSBarry Smith } 13989b94acceSBarry Smith 1399646217ecSPeter Brune 1400646217ecSPeter Brune #undef __FUNCT__ 1401e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction" 1402e4ed7901SPeter Brune /*@C 1403e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1404e4ed7901SPeter Brune function norm at the initialization of the method. In some 1405e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1406e4ed7901SPeter Brune SNESSolve. This function allows one to avoid a redundant call 1407e4ed7901SPeter Brune to SNESComputeFunction in that case. 1408e4ed7901SPeter Brune 1409e4ed7901SPeter Brune Logically Collective on SNES 1410e4ed7901SPeter Brune 1411e4ed7901SPeter Brune Input Parameters: 1412e4ed7901SPeter Brune + snes - the SNES context 1413e4ed7901SPeter Brune - f - vector to store function value 1414e4ed7901SPeter Brune 1415e4ed7901SPeter Brune Notes: 1416e4ed7901SPeter Brune This should not be modified during the solution procedure. 1417e4ed7901SPeter Brune 1418e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1419e4ed7901SPeter Brune 1420e4ed7901SPeter Brune Level: developer 1421e4ed7901SPeter Brune 1422e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function 1423e4ed7901SPeter Brune 1424e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm() 1425e4ed7901SPeter Brune @*/ 1426e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1427e4ed7901SPeter Brune { 1428e4ed7901SPeter Brune PetscErrorCode ierr; 1429e4ed7901SPeter Brune Vec vec_func; 1430e4ed7901SPeter Brune 1431e4ed7901SPeter Brune PetscFunctionBegin; 1432e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1433e4ed7901SPeter Brune PetscValidHeaderSpecific(f,VEC_CLASSID,2); 1434e4ed7901SPeter Brune PetscCheckSameComm(snes,1,f,2); 1435e4ed7901SPeter Brune ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1436e4ed7901SPeter Brune ierr = VecCopy(f, vec_func);CHKERRQ(ierr); 1437217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 1438e4ed7901SPeter Brune PetscFunctionReturn(0); 1439e4ed7901SPeter Brune } 1440e4ed7901SPeter Brune 1441e4ed7901SPeter Brune 1442e4ed7901SPeter Brune #undef __FUNCT__ 1443e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm" 1444e4ed7901SPeter Brune /*@C 1445e4ed7901SPeter Brune SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm 1446e4ed7901SPeter Brune at the initialization of the method. In some instances, the user has precomputed 1447e4ed7901SPeter Brune the function and its norm before calling SNESSolve. This function allows one to 1448e4ed7901SPeter Brune avoid a redundant call to SNESComputeFunction() and VecNorm() in that case. 1449e4ed7901SPeter Brune 1450e4ed7901SPeter Brune Logically Collective on SNES 1451e4ed7901SPeter Brune 1452e4ed7901SPeter Brune Input Parameters: 1453e4ed7901SPeter Brune + snes - the SNES context 1454e4ed7901SPeter Brune - fnorm - the norm of F as set by SNESSetInitialFunction() 1455e4ed7901SPeter Brune 1456e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1457e4ed7901SPeter Brune 1458e4ed7901SPeter Brune Level: developer 1459e4ed7901SPeter Brune 1460e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm 1461e4ed7901SPeter Brune 1462e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction() 1463e4ed7901SPeter Brune @*/ 1464e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm) 1465e4ed7901SPeter Brune { 1466e4ed7901SPeter Brune PetscFunctionBegin; 1467e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1468e4ed7901SPeter Brune snes->norm_init = fnorm; 1469e4ed7901SPeter Brune snes->norm_init_set = PETSC_TRUE; 1470e4ed7901SPeter Brune PetscFunctionReturn(0); 1471e4ed7901SPeter Brune } 1472e4ed7901SPeter Brune 1473e4ed7901SPeter Brune #undef __FUNCT__ 1474534ebe21SPeter Brune #define __FUNCT__ "SNESSetNormType" 1475534ebe21SPeter Brune /*@ 1476534ebe21SPeter Brune SNESSetNormType - Sets the SNESNormType used in covergence and monitoring 1477534ebe21SPeter Brune of the SNES method. 1478534ebe21SPeter Brune 1479534ebe21SPeter Brune Logically Collective on SNES 1480534ebe21SPeter Brune 1481534ebe21SPeter Brune Input Parameters: 1482534ebe21SPeter Brune + snes - the SNES context 1483534ebe21SPeter Brune - normtype - the type of the norm used 1484534ebe21SPeter Brune 1485534ebe21SPeter Brune Notes: 1486534ebe21SPeter Brune Only certain SNES methods support certain SNESNormTypes. Most require evaluation 1487534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1488534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1489534ebe21SPeter Brune (SNESGS) and the like do not require the norm of the function to be computed, and therfore 1490534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1491534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1492534ebe21SPeter Brune their solution. 1493534ebe21SPeter Brune 1494534ebe21SPeter Brune Level: developer 1495534ebe21SPeter Brune 1496534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1497534ebe21SPeter Brune 1498534ebe21SPeter Brune .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType 1499534ebe21SPeter Brune @*/ 1500534ebe21SPeter Brune PetscErrorCode SNESSetNormType(SNES snes, SNESNormType normtype) 1501534ebe21SPeter Brune { 1502534ebe21SPeter Brune PetscFunctionBegin; 1503534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1504534ebe21SPeter Brune snes->normtype = normtype; 1505534ebe21SPeter Brune PetscFunctionReturn(0); 1506534ebe21SPeter Brune } 1507534ebe21SPeter Brune 1508534ebe21SPeter Brune 1509534ebe21SPeter Brune #undef __FUNCT__ 1510534ebe21SPeter Brune #define __FUNCT__ "SNESGetNormType" 1511534ebe21SPeter Brune /*@ 1512534ebe21SPeter Brune SNESGetNormType - Gets the SNESNormType used in covergence and monitoring 1513534ebe21SPeter Brune of the SNES method. 1514534ebe21SPeter Brune 1515534ebe21SPeter Brune Logically Collective on SNES 1516534ebe21SPeter Brune 1517534ebe21SPeter Brune Input Parameters: 1518534ebe21SPeter Brune + snes - the SNES context 1519534ebe21SPeter Brune - normtype - the type of the norm used 1520534ebe21SPeter Brune 1521534ebe21SPeter Brune Level: advanced 1522534ebe21SPeter Brune 1523534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1524534ebe21SPeter Brune 1525534ebe21SPeter Brune .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType 1526534ebe21SPeter Brune @*/ 1527534ebe21SPeter Brune PetscErrorCode SNESGetNormType(SNES snes, SNESNormType *normtype) 1528534ebe21SPeter Brune { 1529534ebe21SPeter Brune PetscFunctionBegin; 1530534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1531534ebe21SPeter Brune *normtype = snes->normtype; 1532534ebe21SPeter Brune PetscFunctionReturn(0); 1533534ebe21SPeter Brune } 1534534ebe21SPeter Brune 1535534ebe21SPeter Brune #undef __FUNCT__ 1536646217ecSPeter Brune #define __FUNCT__ "SNESSetGS" 1537c79ef259SPeter Brune /*@C 1538c79ef259SPeter Brune SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for 1539c79ef259SPeter Brune use with composed nonlinear solvers. 1540c79ef259SPeter Brune 1541c79ef259SPeter Brune Input Parameters: 1542c79ef259SPeter Brune + snes - the SNES context 1543c79ef259SPeter Brune . gsfunc - function evaluation routine 1544c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 1545c79ef259SPeter Brune smoother evaluation routine (may be PETSC_NULL) 1546c79ef259SPeter Brune 1547c79ef259SPeter Brune Calling sequence of func: 1548c79ef259SPeter Brune $ func (SNES snes,Vec x,Vec b,void *ctx); 1549c79ef259SPeter Brune 1550c79ef259SPeter Brune + X - solution vector 1551c79ef259SPeter Brune . B - RHS vector 1552d28543b3SPeter Brune - ctx - optional user-defined Gauss-Seidel context 1553c79ef259SPeter Brune 1554c79ef259SPeter Brune Notes: 1555c79ef259SPeter Brune The GS routines are used by the composed nonlinear solver to generate 1556c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1557c79ef259SPeter Brune 1558d28543b3SPeter Brune Level: intermediate 1559c79ef259SPeter Brune 1560d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1561c79ef259SPeter Brune 1562c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS() 1563c79ef259SPeter Brune @*/ 15646cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx) 15656cab3a1bSJed Brown { 15666cab3a1bSJed Brown PetscErrorCode ierr; 15676cab3a1bSJed Brown DM dm; 15686cab3a1bSJed Brown 1569646217ecSPeter Brune PetscFunctionBegin; 15706cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15716cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 15726cab3a1bSJed Brown ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr); 1573646217ecSPeter Brune PetscFunctionReturn(0); 1574646217ecSPeter Brune } 1575646217ecSPeter Brune 1576d25893d9SBarry Smith #undef __FUNCT__ 157789b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps" 157889b92e6fSPeter Brune /*@ 157989b92e6fSPeter Brune SNESSetGSSweeps - Sets the number of sweeps of GS to use. 158089b92e6fSPeter Brune 158189b92e6fSPeter Brune Input Parameters: 158289b92e6fSPeter Brune + snes - the SNES context 158389b92e6fSPeter Brune - sweeps - the number of sweeps of GS to perform. 158489b92e6fSPeter Brune 158589b92e6fSPeter Brune Level: intermediate 158689b92e6fSPeter Brune 158789b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 158889b92e6fSPeter Brune 158989b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps() 159089b92e6fSPeter Brune @*/ 159189b92e6fSPeter Brune 159289b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) { 159389b92e6fSPeter Brune PetscFunctionBegin; 159489b92e6fSPeter Brune snes->gssweeps = sweeps; 159589b92e6fSPeter Brune PetscFunctionReturn(0); 159689b92e6fSPeter Brune } 159789b92e6fSPeter Brune 159889b92e6fSPeter Brune 159989b92e6fSPeter Brune #undef __FUNCT__ 160089b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps" 160189b92e6fSPeter Brune /*@ 160289b92e6fSPeter Brune SNESGetGSSweeps - Gets the number of sweeps GS will use. 160389b92e6fSPeter Brune 160489b92e6fSPeter Brune Input Parameters: 160589b92e6fSPeter Brune . snes - the SNES context 160689b92e6fSPeter Brune 160789b92e6fSPeter Brune Output Parameters: 160889b92e6fSPeter Brune . sweeps - the number of sweeps of GS to perform. 160989b92e6fSPeter Brune 161089b92e6fSPeter Brune Level: intermediate 161189b92e6fSPeter Brune 161289b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 161389b92e6fSPeter Brune 161489b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps() 161589b92e6fSPeter Brune @*/ 161689b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) { 161789b92e6fSPeter Brune PetscFunctionBegin; 161889b92e6fSPeter Brune *sweeps = snes->gssweeps; 161989b92e6fSPeter Brune PetscFunctionReturn(0); 162089b92e6fSPeter Brune } 162189b92e6fSPeter Brune 162289b92e6fSPeter Brune #undef __FUNCT__ 16238b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 16248b0a5094SBarry Smith PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 16258b0a5094SBarry Smith { 16268b0a5094SBarry Smith PetscErrorCode ierr; 16276cab3a1bSJed Brown void *functx,*jacctx; 16286cab3a1bSJed Brown 16298b0a5094SBarry Smith PetscFunctionBegin; 16306cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 16316cab3a1bSJed Brown ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr); 16328b0a5094SBarry Smith /* A(x)*x - b(x) */ 16336cab3a1bSJed Brown ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr); 16346cab3a1bSJed Brown ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr); 16358b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 16368b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 16378b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 16388b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 16398b0a5094SBarry Smith PetscFunctionReturn(0); 16408b0a5094SBarry Smith } 16418b0a5094SBarry Smith 16428b0a5094SBarry Smith #undef __FUNCT__ 16438b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 16448b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 16458b0a5094SBarry Smith { 16468b0a5094SBarry Smith PetscFunctionBegin; 16478b0a5094SBarry Smith *flag = snes->matstruct; 16488b0a5094SBarry Smith PetscFunctionReturn(0); 16498b0a5094SBarry Smith } 16508b0a5094SBarry Smith 16518b0a5094SBarry Smith #undef __FUNCT__ 16528b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 16538b0a5094SBarry Smith /*@C 16540d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 16558b0a5094SBarry Smith 16568b0a5094SBarry Smith Logically Collective on SNES 16578b0a5094SBarry Smith 16588b0a5094SBarry Smith Input Parameters: 16598b0a5094SBarry Smith + snes - the SNES context 16608b0a5094SBarry Smith . r - vector to store function value 16618b0a5094SBarry Smith . func - function evaluation routine 16628b0a5094SBarry 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) 16638b0a5094SBarry Smith . mat - matrix to store A 16648b0a5094SBarry Smith . mfunc - function to compute matrix value 16658b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 16668b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 16678b0a5094SBarry Smith 16688b0a5094SBarry Smith Calling sequence of func: 16698b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 16708b0a5094SBarry Smith 16718b0a5094SBarry Smith + f - function vector 16728b0a5094SBarry Smith - ctx - optional user-defined function context 16738b0a5094SBarry Smith 16748b0a5094SBarry Smith Calling sequence of mfunc: 16758b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 16768b0a5094SBarry Smith 16778b0a5094SBarry Smith + x - input vector 16788b0a5094SBarry 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(), 16798b0a5094SBarry Smith normally just pass mat in this location 16808b0a5094SBarry Smith . mat - form A(x) matrix 16818b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 16828b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 16838b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 16848b0a5094SBarry Smith 16858b0a5094SBarry Smith Notes: 16868b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 16878b0a5094SBarry Smith 16888b0a5094SBarry 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} 16898b0a5094SBarry 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. 16908b0a5094SBarry Smith 16918b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 16928b0a5094SBarry Smith 16930d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 16940d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 16958b0a5094SBarry Smith 16968b0a5094SBarry 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 16978b0a5094SBarry 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 16988b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 16998b0a5094SBarry Smith 17008b0a5094SBarry Smith Level: beginner 17018b0a5094SBarry Smith 17028b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 17038b0a5094SBarry Smith 17040d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard() 17058b0a5094SBarry Smith @*/ 17068b0a5094SBarry 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) 17078b0a5094SBarry Smith { 17088b0a5094SBarry Smith PetscErrorCode ierr; 17098b0a5094SBarry Smith PetscFunctionBegin; 17108b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 17118b0a5094SBarry Smith snes->ops->computepfunction = func; 17128b0a5094SBarry Smith snes->ops->computepjacobian = mfunc; 17138b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 17148b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 17158b0a5094SBarry Smith PetscFunctionReturn(0); 17168b0a5094SBarry Smith } 17178b0a5094SBarry Smith 17188b0a5094SBarry Smith #undef __FUNCT__ 1719d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1720d25893d9SBarry Smith /*@C 1721d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1722d25893d9SBarry Smith 1723d25893d9SBarry Smith Logically Collective on SNES 1724d25893d9SBarry Smith 1725d25893d9SBarry Smith Input Parameters: 1726d25893d9SBarry Smith + snes - the SNES context 1727d25893d9SBarry Smith . func - function evaluation routine 1728d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1729d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1730d25893d9SBarry Smith 1731d25893d9SBarry Smith Calling sequence of func: 1732d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1733d25893d9SBarry Smith 1734d25893d9SBarry Smith . f - function vector 1735d25893d9SBarry Smith - ctx - optional user-defined function context 1736d25893d9SBarry Smith 1737d25893d9SBarry Smith Level: intermediate 1738d25893d9SBarry Smith 1739d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1740d25893d9SBarry Smith 1741d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1742d25893d9SBarry Smith @*/ 1743d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1744d25893d9SBarry Smith { 1745d25893d9SBarry Smith PetscFunctionBegin; 1746d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1747d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1748d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1749d25893d9SBarry Smith PetscFunctionReturn(0); 1750d25893d9SBarry Smith } 1751d25893d9SBarry Smith 17523ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 17533ab0aad5SBarry Smith #undef __FUNCT__ 17541096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 17551096aae1SMatthew Knepley /*@C 17561096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 17571096aae1SMatthew Knepley it assumes a zero right hand side. 17581096aae1SMatthew Knepley 17593f9fe445SBarry Smith Logically Collective on SNES 17601096aae1SMatthew Knepley 17611096aae1SMatthew Knepley Input Parameter: 17621096aae1SMatthew Knepley . snes - the SNES context 17631096aae1SMatthew Knepley 17641096aae1SMatthew Knepley Output Parameter: 1765bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 17661096aae1SMatthew Knepley 17671096aae1SMatthew Knepley Level: intermediate 17681096aae1SMatthew Knepley 17691096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 17701096aae1SMatthew Knepley 177185385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 17721096aae1SMatthew Knepley @*/ 17737087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 17741096aae1SMatthew Knepley { 17751096aae1SMatthew Knepley PetscFunctionBegin; 17760700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 17771096aae1SMatthew Knepley PetscValidPointer(rhs,2); 177885385478SLisandro Dalcin *rhs = snes->vec_rhs; 17791096aae1SMatthew Knepley PetscFunctionReturn(0); 17801096aae1SMatthew Knepley } 17811096aae1SMatthew Knepley 17821096aae1SMatthew Knepley #undef __FUNCT__ 17834a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 17849b94acceSBarry Smith /*@ 178536851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 17869b94acceSBarry Smith SNESSetFunction(). 17879b94acceSBarry Smith 1788c7afd0dbSLois Curfman McInnes Collective on SNES 1789c7afd0dbSLois Curfman McInnes 17909b94acceSBarry Smith Input Parameters: 1791c7afd0dbSLois Curfman McInnes + snes - the SNES context 1792c7afd0dbSLois Curfman McInnes - x - input vector 17939b94acceSBarry Smith 17949b94acceSBarry Smith Output Parameter: 17953638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 17969b94acceSBarry Smith 17971bffabb2SLois Curfman McInnes Notes: 179836851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 179936851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 180036851e7fSLois Curfman McInnes themselves. 180136851e7fSLois Curfman McInnes 180236851e7fSLois Curfman McInnes Level: developer 180336851e7fSLois Curfman McInnes 18049b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 18059b94acceSBarry Smith 1806a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 18079b94acceSBarry Smith @*/ 18087087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 18099b94acceSBarry Smith { 1810dfbe8321SBarry Smith PetscErrorCode ierr; 18116cab3a1bSJed Brown DM dm; 18126cab3a1bSJed Brown SNESDM sdm; 18139b94acceSBarry Smith 18143a40ed3dSBarry Smith PetscFunctionBegin; 18150700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 18160700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 18170700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1818c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1819c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 18204ec14c9cSBarry Smith VecValidValues(x,2,PETSC_TRUE); 1821184914b5SBarry Smith 18226cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18236cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 1824d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 18256cab3a1bSJed Brown if (sdm->computefunction) { 1826d64ed03dSBarry Smith PetscStackPush("SNES user function"); 18276cab3a1bSJed Brown ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 1828d64ed03dSBarry Smith PetscStackPop; 182973250ac0SBarry Smith } else if (snes->dm) { 1830644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1831c90fad12SPeter Brune } else if (snes->vec_rhs) { 1832c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1833644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 183485385478SLisandro Dalcin if (snes->vec_rhs) { 183585385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 18363ab0aad5SBarry Smith } 1837ae3c334cSLois Curfman McInnes snes->nfuncs++; 1838d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 18394ec14c9cSBarry Smith VecValidValues(y,3,PETSC_FALSE); 18403a40ed3dSBarry Smith PetscFunctionReturn(0); 18419b94acceSBarry Smith } 18429b94acceSBarry Smith 18434a2ae208SSatish Balay #undef __FUNCT__ 1844646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1845c79ef259SPeter Brune /*@ 1846c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1847c79ef259SPeter Brune SNESSetGS(). 1848c79ef259SPeter Brune 1849c79ef259SPeter Brune Collective on SNES 1850c79ef259SPeter Brune 1851c79ef259SPeter Brune Input Parameters: 1852c79ef259SPeter Brune + snes - the SNES context 1853c79ef259SPeter Brune . x - input vector 1854c79ef259SPeter Brune - b - rhs vector 1855c79ef259SPeter Brune 1856c79ef259SPeter Brune Output Parameter: 1857c79ef259SPeter Brune . x - new solution vector 1858c79ef259SPeter Brune 1859c79ef259SPeter Brune Notes: 1860c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1861c79ef259SPeter Brune implementations, so most users would not generally call this routine 1862c79ef259SPeter Brune themselves. 1863c79ef259SPeter Brune 1864c79ef259SPeter Brune Level: developer 1865c79ef259SPeter Brune 1866c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1867c79ef259SPeter Brune 1868c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1869c79ef259SPeter Brune @*/ 1870646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1871646217ecSPeter Brune { 1872646217ecSPeter Brune PetscErrorCode ierr; 187389b92e6fSPeter Brune PetscInt i; 18746cab3a1bSJed Brown DM dm; 18756cab3a1bSJed Brown SNESDM sdm; 1876646217ecSPeter Brune 1877646217ecSPeter Brune PetscFunctionBegin; 1878646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1879646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1880646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1881646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 1882646217ecSPeter Brune if(b) PetscCheckSameComm(snes,1,b,3); 18834ec14c9cSBarry Smith if (b) VecValidValues(b,2,PETSC_TRUE); 1884701cf23dSPeter Brune ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 18856cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18866cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 18876cab3a1bSJed Brown if (sdm->computegs) { 188889b92e6fSPeter Brune for (i = 0; i < snes->gssweeps; i++) { 1889646217ecSPeter Brune PetscStackPush("SNES user GS"); 18906cab3a1bSJed Brown ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 1891646217ecSPeter Brune PetscStackPop; 189289b92e6fSPeter Brune } 1893646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 1894701cf23dSPeter Brune ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 18954ec14c9cSBarry Smith VecValidValues(x,3,PETSC_FALSE); 1896646217ecSPeter Brune PetscFunctionReturn(0); 1897646217ecSPeter Brune } 1898646217ecSPeter Brune 1899646217ecSPeter Brune 1900646217ecSPeter Brune #undef __FUNCT__ 19014a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 190262fef451SLois Curfman McInnes /*@ 190362fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 190462fef451SLois Curfman McInnes set with SNESSetJacobian(). 190562fef451SLois Curfman McInnes 1906c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1907c7afd0dbSLois Curfman McInnes 190862fef451SLois Curfman McInnes Input Parameters: 1909c7afd0dbSLois Curfman McInnes + snes - the SNES context 1910c7afd0dbSLois Curfman McInnes - x - input vector 191162fef451SLois Curfman McInnes 191262fef451SLois Curfman McInnes Output Parameters: 1913c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 191462fef451SLois Curfman McInnes . B - optional preconditioning matrix 19152b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1916fee21e36SBarry Smith 1917e35cf81dSBarry Smith Options Database Keys: 1918e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1919693365a8SJed Brown . -snes_lag_jacobian <lag> 1920693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1921693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1922693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 19234c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1924c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 1925c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 1926c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 1927c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 1928c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 19294c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 1930c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 1931c01495d3SJed Brown 1932e35cf81dSBarry Smith 193362fef451SLois Curfman McInnes Notes: 193462fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 193562fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 193662fef451SLois Curfman McInnes 193794b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1938dc5a77f8SLois Curfman McInnes flag parameter. 193962fef451SLois Curfman McInnes 194036851e7fSLois Curfman McInnes Level: developer 194136851e7fSLois Curfman McInnes 194262fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 194362fef451SLois Curfman McInnes 1944e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 194562fef451SLois Curfman McInnes @*/ 19467087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 19479b94acceSBarry Smith { 1948dfbe8321SBarry Smith PetscErrorCode ierr; 1949ace3abfcSBarry Smith PetscBool flag; 19506cab3a1bSJed Brown DM dm; 19516cab3a1bSJed Brown SNESDM sdm; 19523a40ed3dSBarry Smith 19533a40ed3dSBarry Smith PetscFunctionBegin; 19540700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 19550700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 19564482741eSBarry Smith PetscValidPointer(flg,5); 1957c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 19584ec14c9cSBarry Smith VecValidValues(X,2,PETSC_TRUE); 19596cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 19606cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 19616cab3a1bSJed Brown if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 1962ebd3b9afSBarry Smith 1963ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1964ebd3b9afSBarry Smith 1965fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 1966fe3ffe1eSBarry Smith snes->lagjacobian = -1; 1967fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1968fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 1969e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1970e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1971251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1972ebd3b9afSBarry Smith if (flag) { 1973ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1974ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1975ebd3b9afSBarry Smith } 1976e35cf81dSBarry Smith PetscFunctionReturn(0); 1977e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1978e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1979e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1980251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1981ebd3b9afSBarry Smith if (flag) { 1982ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1983ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1984ebd3b9afSBarry Smith } 1985e35cf81dSBarry Smith PetscFunctionReturn(0); 1986e35cf81dSBarry Smith } 1987e35cf81dSBarry Smith 1988c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 1989e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1990d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 19916cab3a1bSJed Brown ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr); 1992d64ed03dSBarry Smith PetscStackPop; 1993d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1994a8054027SBarry Smith 19953b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 19963b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 19973b4f5425SBarry Smith snes->lagpreconditioner = -1; 19983b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 1999a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 2000a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 2001a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 2002a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 2003a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 2004a8054027SBarry Smith } 2005a8054027SBarry Smith 20066d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 20070700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 20080700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 2009693365a8SJed Brown { 2010693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 2011693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 2012693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 2013693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 2014693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 2015693365a8SJed Brown if (flag || flag_draw || flag_contour) { 2016693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 2017693365a8SJed Brown MatStructure mstruct; 2018693365a8SJed Brown PetscViewer vdraw,vstdout; 20196b3a5b13SJed Brown PetscBool flg; 2020693365a8SJed Brown if (flag_operator) { 2021693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 2022693365a8SJed Brown Bexp = Bexp_mine; 2023693365a8SJed Brown } else { 2024693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 2025251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 2026693365a8SJed Brown if (flg) Bexp = *B; 2027693365a8SJed Brown else { 2028693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 2029693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 2030693365a8SJed Brown Bexp = Bexp_mine; 2031693365a8SJed Brown } 2032693365a8SJed Brown } 2033693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 2034693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 2035693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 2036693365a8SJed Brown if (flag_draw || flag_contour) { 2037693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2038693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 2039693365a8SJed Brown } else vdraw = PETSC_NULL; 2040693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 2041693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 2042693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 2043693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 2044693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2045693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 2046693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2047693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 2048693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2049693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 2050693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2051693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 2052693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2053693365a8SJed Brown } 2054693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2055693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2056693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 2057693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 2058693365a8SJed Brown } 2059693365a8SJed Brown } 20604c30e9fbSJed Brown { 20616719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 20626719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 20634c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 20646719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 20654c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 20664c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 20676719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 20686719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 20696719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 20706719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 20714c30e9fbSJed Brown Mat Bfd; 20724c30e9fbSJed Brown MatStructure mstruct; 20734c30e9fbSJed Brown PetscViewer vdraw,vstdout; 20744c30e9fbSJed Brown ISColoring iscoloring; 20754c30e9fbSJed Brown MatFDColoring matfdcoloring; 20764c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 20774c30e9fbSJed Brown void *funcctx; 20786719d8e4SJed Brown PetscReal norm1,norm2,normmax; 20794c30e9fbSJed Brown 20804c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 20814c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 20824c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 20834c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 20844c30e9fbSJed Brown 20854c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 20864c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 20874c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 20884c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 20894c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 20904c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 20914c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 20924c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 20934c30e9fbSJed Brown 20944c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 20954c30e9fbSJed Brown if (flag_draw || flag_contour) { 20964c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 20974c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 20984c30e9fbSJed Brown } else vdraw = PETSC_NULL; 20994c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 21006719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 21014c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 21024c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 21036719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 21044c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 21054c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 21064c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 21076719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 21084c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 21096719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 21106719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 21114c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 21124c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 21134c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 21144c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 21154c30e9fbSJed Brown } 21164c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 21176719d8e4SJed Brown 21186719d8e4SJed Brown if (flag_threshold) { 21196719d8e4SJed Brown PetscInt bs,rstart,rend,i; 21206719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 21216719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 21226719d8e4SJed Brown for (i=rstart; i<rend; i++) { 21236719d8e4SJed Brown const PetscScalar *ba,*ca; 21246719d8e4SJed Brown const PetscInt *bj,*cj; 21256719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 21266719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 21276719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 21286719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 21296719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 21306719d8e4SJed Brown for (j=0; j<bn; j++) { 21316719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 21326719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 21336719d8e4SJed Brown maxentrycol = bj[j]; 21346719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 21356719d8e4SJed Brown } 21366719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 21376719d8e4SJed Brown maxdiffcol = bj[j]; 21386719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 21396719d8e4SJed Brown } 21406719d8e4SJed Brown if (rdiff > maxrdiff) { 21416719d8e4SJed Brown maxrdiffcol = bj[j]; 21426719d8e4SJed Brown maxrdiff = rdiff; 21436719d8e4SJed Brown } 21446719d8e4SJed Brown } 21456719d8e4SJed Brown if (maxrdiff > 1) { 21466719d8e4SJed 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); 21476719d8e4SJed Brown for (j=0; j<bn; j++) { 21486719d8e4SJed Brown PetscReal rdiff; 21496719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 21506719d8e4SJed Brown if (rdiff > 1) { 21516719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 21526719d8e4SJed Brown } 21536719d8e4SJed Brown } 21546719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 21556719d8e4SJed Brown } 21566719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 21576719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 21586719d8e4SJed Brown } 21596719d8e4SJed Brown } 21604c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 21614c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 21624c30e9fbSJed Brown } 21634c30e9fbSJed Brown } 21643a40ed3dSBarry Smith PetscFunctionReturn(0); 21659b94acceSBarry Smith } 21669b94acceSBarry Smith 21674a2ae208SSatish Balay #undef __FUNCT__ 21684a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 21699b94acceSBarry Smith /*@C 21709b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2171044dda88SLois Curfman McInnes location to store the matrix. 21729b94acceSBarry Smith 21733f9fe445SBarry Smith Logically Collective on SNES and Mat 2174c7afd0dbSLois Curfman McInnes 21759b94acceSBarry Smith Input Parameters: 2176c7afd0dbSLois Curfman McInnes + snes - the SNES context 21779b94acceSBarry Smith . A - Jacobian matrix 21789b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 2179efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 2180c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 2181efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 21829b94acceSBarry Smith 21839b94acceSBarry Smith Calling sequence of func: 21848d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 21859b94acceSBarry Smith 2186c7afd0dbSLois Curfman McInnes + x - input vector 21879b94acceSBarry Smith . A - Jacobian matrix 21889b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 2189ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 21902b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 2191c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 21929b94acceSBarry Smith 21939b94acceSBarry Smith Notes: 219494b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 21952cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 2196ac21db08SLois Curfman McInnes 2197ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 21989b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 21999b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 22009b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 22019b94acceSBarry Smith throughout the global iterations. 22029b94acceSBarry Smith 220316913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 220416913363SBarry Smith each matrix. 220516913363SBarry Smith 2206a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 2207a8a26c1eSJed Brown must be a MatFDColoring. 2208a8a26c1eSJed Brown 2209c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2210c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2211c3cc8fd1SJed Brown 221236851e7fSLois Curfman McInnes Level: beginner 221336851e7fSLois Curfman McInnes 22149b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 22159b94acceSBarry Smith 22163ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 22179b94acceSBarry Smith @*/ 22187087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 22199b94acceSBarry Smith { 2220dfbe8321SBarry Smith PetscErrorCode ierr; 22216cab3a1bSJed Brown DM dm; 22223a7fca6bSBarry Smith 22233a40ed3dSBarry Smith PetscFunctionBegin; 22240700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 22250700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 22260700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 2227c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 222806975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 22296cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 22306cab3a1bSJed Brown ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr); 22313a7fca6bSBarry Smith if (A) { 22327dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 22336bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 22349b94acceSBarry Smith snes->jacobian = A; 22353a7fca6bSBarry Smith } 22363a7fca6bSBarry Smith if (B) { 22377dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 22386bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 22399b94acceSBarry Smith snes->jacobian_pre = B; 22403a7fca6bSBarry Smith } 22413a40ed3dSBarry Smith PetscFunctionReturn(0); 22429b94acceSBarry Smith } 224362fef451SLois Curfman McInnes 22444a2ae208SSatish Balay #undef __FUNCT__ 22454a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 2246c2aafc4cSSatish Balay /*@C 2247b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2248b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2249b4fd4287SBarry Smith 2250c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2251c7afd0dbSLois Curfman McInnes 2252b4fd4287SBarry Smith Input Parameter: 2253b4fd4287SBarry Smith . snes - the nonlinear solver context 2254b4fd4287SBarry Smith 2255b4fd4287SBarry Smith Output Parameters: 2256c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 2257b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 225870e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 225970e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 2260fee21e36SBarry Smith 226136851e7fSLois Curfman McInnes Level: advanced 226236851e7fSLois Curfman McInnes 2263b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 2264b4fd4287SBarry Smith @*/ 22657087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 2266b4fd4287SBarry Smith { 22676cab3a1bSJed Brown PetscErrorCode ierr; 22686cab3a1bSJed Brown DM dm; 22696cab3a1bSJed Brown SNESDM sdm; 22706cab3a1bSJed Brown 22713a40ed3dSBarry Smith PetscFunctionBegin; 22720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2273b4fd4287SBarry Smith if (A) *A = snes->jacobian; 2274b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 22756cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 22766cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 22776cab3a1bSJed Brown if (func) *func = sdm->computejacobian; 22786cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 22793a40ed3dSBarry Smith PetscFunctionReturn(0); 2280b4fd4287SBarry Smith } 2281b4fd4287SBarry Smith 22829b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 22839b94acceSBarry Smith 22844a2ae208SSatish Balay #undef __FUNCT__ 22854a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 22869b94acceSBarry Smith /*@ 22879b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2288272ac6f2SLois Curfman McInnes of a nonlinear solver. 22899b94acceSBarry Smith 2290fee21e36SBarry Smith Collective on SNES 2291fee21e36SBarry Smith 2292c7afd0dbSLois Curfman McInnes Input Parameters: 229370e92668SMatthew Knepley . snes - the SNES context 2294c7afd0dbSLois Curfman McInnes 2295272ac6f2SLois Curfman McInnes Notes: 2296272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2297272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2298272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2299272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2300272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2301272ac6f2SLois Curfman McInnes 230236851e7fSLois Curfman McInnes Level: advanced 230336851e7fSLois Curfman McInnes 23049b94acceSBarry Smith .keywords: SNES, nonlinear, setup 23059b94acceSBarry Smith 23069b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 23079b94acceSBarry Smith @*/ 23087087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 23099b94acceSBarry Smith { 2310dfbe8321SBarry Smith PetscErrorCode ierr; 23116cab3a1bSJed Brown DM dm; 23126cab3a1bSJed Brown SNESDM sdm; 23136e2a1849SPeter Brune SNESLineSearch linesearch; 23146e2a1849SPeter Brune SNESLineSearch pclinesearch; 23156e2a1849SPeter Brune void *lsprectx,*lspostctx; 23166e2a1849SPeter Brune SNESLineSearchPreCheckFunc lsprefunc; 23176e2a1849SPeter Brune SNESLineSearchPostCheckFunc lspostfunc; 23186e2a1849SPeter Brune PetscErrorCode (*func)(SNES,Vec,Vec,void*); 23196e2a1849SPeter Brune Vec f,fpc; 23206e2a1849SPeter Brune void *funcctx; 23216e2a1849SPeter Brune PetscErrorCode (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 23226e2a1849SPeter Brune void *jacctx; 23236e2a1849SPeter Brune Mat A,B; 23243a40ed3dSBarry Smith 23253a40ed3dSBarry Smith PetscFunctionBegin; 23260700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23274dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 23289b94acceSBarry Smith 23297adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 233085385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 233185385478SLisandro Dalcin } 233285385478SLisandro Dalcin 2333a63bb30eSJed Brown ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 233417186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 233558c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 233658c9b817SLisandro Dalcin 233758c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 233858c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 233958c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 234058c9b817SLisandro Dalcin } 234158c9b817SLisandro Dalcin 23426cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 23436cab3a1bSJed Brown ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */ 23446cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 23456cab3a1bSJed Brown if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc"); 23466cab3a1bSJed Brown if (!snes->vec_func) { 23476cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2348214df951SJed Brown } 2349efd51863SBarry Smith 2350b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 2351b710008aSBarry Smith 2352f1c6b773SPeter Brune if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);} 23539e764e56SPeter Brune 2354d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 2355d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2356d25893d9SBarry Smith } 2357d25893d9SBarry Smith 23586e2a1849SPeter Brune if (snes->pc) { 23596e2a1849SPeter Brune /* copy the DM over */ 23606e2a1849SPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 23616e2a1849SPeter Brune ierr = SNESSetDM(snes->pc,dm);CHKERRQ(ierr); 23626e2a1849SPeter Brune 23636e2a1849SPeter Brune /* copy the legacy SNES context not related to the DM over*/ 23646e2a1849SPeter Brune ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr); 23656e2a1849SPeter Brune ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr); 23666e2a1849SPeter Brune ierr = SNESSetFunction(snes->pc,fpc,func,funcctx);CHKERRQ(ierr); 23676e2a1849SPeter Brune ierr = SNESGetJacobian(snes,&A,&B,&jac,&jacctx);CHKERRQ(ierr); 23686e2a1849SPeter Brune ierr = SNESSetJacobian(snes->pc,A,B,jac,jacctx);CHKERRQ(ierr); 23696e2a1849SPeter Brune ierr = VecDestroy(&fpc);CHKERRQ(ierr); 23706e2a1849SPeter Brune 23716e2a1849SPeter Brune /* copy the function pointers over */ 23726e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr); 23736e2a1849SPeter Brune 23746e2a1849SPeter Brune /* default to 1 iteration */ 23756e2a1849SPeter Brune ierr = SNESSetTolerances(snes->pc, snes->pc->abstol, snes->pc->rtol, snes->pc->stol, 1, snes->pc->max_funcs);CHKERRQ(ierr); 23766e2a1849SPeter Brune ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); 23776e2a1849SPeter Brune ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 23786e2a1849SPeter Brune 23796e2a1849SPeter Brune /* copy the line search context over */ 23806e2a1849SPeter Brune ierr = SNESGetSNESLineSearch(snes,&linesearch);CHKERRQ(ierr); 23816e2a1849SPeter Brune ierr = SNESGetSNESLineSearch(snes->pc,&pclinesearch);CHKERRQ(ierr); 23826e2a1849SPeter Brune ierr = SNESLineSearchGetPreCheck(linesearch,&lsprefunc,&lsprectx);CHKERRQ(ierr); 23836e2a1849SPeter Brune ierr = SNESLineSearchGetPostCheck(linesearch,&lspostfunc,&lspostctx);CHKERRQ(ierr); 23846e2a1849SPeter Brune ierr = SNESLineSearchSetPreCheck(pclinesearch,lsprefunc,lsprectx);CHKERRQ(ierr); 23856e2a1849SPeter Brune ierr = SNESLineSearchSetPostCheck(pclinesearch,lspostfunc,lspostctx);CHKERRQ(ierr); 23866e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr); 23876e2a1849SPeter Brune } 23886e2a1849SPeter Brune 2389410397dcSLisandro Dalcin if (snes->ops->setup) { 2390410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2391410397dcSLisandro Dalcin } 239258c9b817SLisandro Dalcin 23937aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 23943a40ed3dSBarry Smith PetscFunctionReturn(0); 23959b94acceSBarry Smith } 23969b94acceSBarry Smith 23974a2ae208SSatish Balay #undef __FUNCT__ 239837596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 239937596af1SLisandro Dalcin /*@ 240037596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 240137596af1SLisandro Dalcin 240237596af1SLisandro Dalcin Collective on SNES 240337596af1SLisandro Dalcin 240437596af1SLisandro Dalcin Input Parameter: 240537596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 240637596af1SLisandro Dalcin 2407d25893d9SBarry Smith Level: intermediate 2408d25893d9SBarry Smith 2409d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 241037596af1SLisandro Dalcin 241137596af1SLisandro Dalcin .keywords: SNES, destroy 241237596af1SLisandro Dalcin 241337596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 241437596af1SLisandro Dalcin @*/ 241537596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 241637596af1SLisandro Dalcin { 241737596af1SLisandro Dalcin PetscErrorCode ierr; 241837596af1SLisandro Dalcin 241937596af1SLisandro Dalcin PetscFunctionBegin; 242037596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2421d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2422d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2423d25893d9SBarry Smith snes->user = PETSC_NULL; 2424d25893d9SBarry Smith } 24258a23116dSBarry Smith if (snes->pc) { 24268a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 24278a23116dSBarry Smith } 24288a23116dSBarry Smith 242937596af1SLisandro Dalcin if (snes->ops->reset) { 243037596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 243137596af1SLisandro Dalcin } 24329e764e56SPeter Brune if (snes->ksp) { 24339e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 24349e764e56SPeter Brune } 24359e764e56SPeter Brune 24369e764e56SPeter Brune if (snes->linesearch) { 2437f1c6b773SPeter Brune ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 24389e764e56SPeter Brune } 24399e764e56SPeter Brune 24406bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 24416bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 24426bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 24436bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 24446bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 24456bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2446c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2447c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 244837596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 244937596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 245037596af1SLisandro Dalcin PetscFunctionReturn(0); 245137596af1SLisandro Dalcin } 245237596af1SLisandro Dalcin 245337596af1SLisandro Dalcin #undef __FUNCT__ 24544a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 245552baeb72SSatish Balay /*@ 24569b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 24579b94acceSBarry Smith with SNESCreate(). 24589b94acceSBarry Smith 2459c7afd0dbSLois Curfman McInnes Collective on SNES 2460c7afd0dbSLois Curfman McInnes 24619b94acceSBarry Smith Input Parameter: 24629b94acceSBarry Smith . snes - the SNES context 24639b94acceSBarry Smith 246436851e7fSLois Curfman McInnes Level: beginner 246536851e7fSLois Curfman McInnes 24669b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 24679b94acceSBarry Smith 246863a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 24699b94acceSBarry Smith @*/ 24706bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 24719b94acceSBarry Smith { 24726849ba73SBarry Smith PetscErrorCode ierr; 24733a40ed3dSBarry Smith 24743a40ed3dSBarry Smith PetscFunctionBegin; 24756bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 24766bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 24776bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2478d4bb536fSBarry Smith 24796bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 24808a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 24816b8b9a38SLisandro Dalcin 2482be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 24836bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 24846bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 24856d4c513bSLisandro Dalcin 24866bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 24876bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 2488f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 24896b8b9a38SLisandro Dalcin 24906bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 24916bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 24926bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 24936b8b9a38SLisandro Dalcin } 24946bf464f9SBarry Smith if ((*snes)->conv_malloc) { 24956bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 24966bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 249758c9b817SLisandro Dalcin } 24986bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2499a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 25003a40ed3dSBarry Smith PetscFunctionReturn(0); 25019b94acceSBarry Smith } 25029b94acceSBarry Smith 25039b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 25049b94acceSBarry Smith 25054a2ae208SSatish Balay #undef __FUNCT__ 2506a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2507a8054027SBarry Smith /*@ 2508a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2509a8054027SBarry Smith 25103f9fe445SBarry Smith Logically Collective on SNES 2511a8054027SBarry Smith 2512a8054027SBarry Smith Input Parameters: 2513a8054027SBarry Smith + snes - the SNES context 2514a8054027SBarry 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 25153b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2516a8054027SBarry Smith 2517a8054027SBarry Smith Options Database Keys: 2518a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2519a8054027SBarry Smith 2520a8054027SBarry Smith Notes: 2521a8054027SBarry Smith The default is 1 2522a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2523a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2524a8054027SBarry Smith 2525a8054027SBarry Smith Level: intermediate 2526a8054027SBarry Smith 2527a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2528a8054027SBarry Smith 2529e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2530a8054027SBarry Smith 2531a8054027SBarry Smith @*/ 25327087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2533a8054027SBarry Smith { 2534a8054027SBarry Smith PetscFunctionBegin; 25350700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2536e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2537e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2538c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2539a8054027SBarry Smith snes->lagpreconditioner = lag; 2540a8054027SBarry Smith PetscFunctionReturn(0); 2541a8054027SBarry Smith } 2542a8054027SBarry Smith 2543a8054027SBarry Smith #undef __FUNCT__ 2544efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2545efd51863SBarry Smith /*@ 2546efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2547efd51863SBarry Smith 2548efd51863SBarry Smith Logically Collective on SNES 2549efd51863SBarry Smith 2550efd51863SBarry Smith Input Parameters: 2551efd51863SBarry Smith + snes - the SNES context 2552efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2553efd51863SBarry Smith 2554efd51863SBarry Smith Options Database Keys: 2555efd51863SBarry Smith . -snes_grid_sequence <steps> 2556efd51863SBarry Smith 2557efd51863SBarry Smith Level: intermediate 2558efd51863SBarry Smith 2559c0df2a02SJed Brown Notes: 2560c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2561c0df2a02SJed Brown 2562efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2563efd51863SBarry Smith 2564efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2565efd51863SBarry Smith 2566efd51863SBarry Smith @*/ 2567efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2568efd51863SBarry Smith { 2569efd51863SBarry Smith PetscFunctionBegin; 2570efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2571efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2572efd51863SBarry Smith snes->gridsequence = steps; 2573efd51863SBarry Smith PetscFunctionReturn(0); 2574efd51863SBarry Smith } 2575efd51863SBarry Smith 2576efd51863SBarry Smith #undef __FUNCT__ 2577a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2578a8054027SBarry Smith /*@ 2579a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2580a8054027SBarry Smith 25813f9fe445SBarry Smith Not Collective 2582a8054027SBarry Smith 2583a8054027SBarry Smith Input Parameter: 2584a8054027SBarry Smith . snes - the SNES context 2585a8054027SBarry Smith 2586a8054027SBarry Smith Output Parameter: 2587a8054027SBarry 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 25883b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2589a8054027SBarry Smith 2590a8054027SBarry Smith Options Database Keys: 2591a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2592a8054027SBarry Smith 2593a8054027SBarry Smith Notes: 2594a8054027SBarry Smith The default is 1 2595a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2596a8054027SBarry Smith 2597a8054027SBarry Smith Level: intermediate 2598a8054027SBarry Smith 2599a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2600a8054027SBarry Smith 2601a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2602a8054027SBarry Smith 2603a8054027SBarry Smith @*/ 26047087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2605a8054027SBarry Smith { 2606a8054027SBarry Smith PetscFunctionBegin; 26070700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2608a8054027SBarry Smith *lag = snes->lagpreconditioner; 2609a8054027SBarry Smith PetscFunctionReturn(0); 2610a8054027SBarry Smith } 2611a8054027SBarry Smith 2612a8054027SBarry Smith #undef __FUNCT__ 2613e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2614e35cf81dSBarry Smith /*@ 2615e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2616e35cf81dSBarry Smith often the preconditioner is rebuilt. 2617e35cf81dSBarry Smith 26183f9fe445SBarry Smith Logically Collective on SNES 2619e35cf81dSBarry Smith 2620e35cf81dSBarry Smith Input Parameters: 2621e35cf81dSBarry Smith + snes - the SNES context 2622e35cf81dSBarry 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 2623fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2624e35cf81dSBarry Smith 2625e35cf81dSBarry Smith Options Database Keys: 2626e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2627e35cf81dSBarry Smith 2628e35cf81dSBarry Smith Notes: 2629e35cf81dSBarry Smith The default is 1 2630e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2631fe3ffe1eSBarry 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 2632fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2633e35cf81dSBarry Smith 2634e35cf81dSBarry Smith Level: intermediate 2635e35cf81dSBarry Smith 2636e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2637e35cf81dSBarry Smith 2638e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2639e35cf81dSBarry Smith 2640e35cf81dSBarry Smith @*/ 26417087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2642e35cf81dSBarry Smith { 2643e35cf81dSBarry Smith PetscFunctionBegin; 26440700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2645e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2646e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2647c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2648e35cf81dSBarry Smith snes->lagjacobian = lag; 2649e35cf81dSBarry Smith PetscFunctionReturn(0); 2650e35cf81dSBarry Smith } 2651e35cf81dSBarry Smith 2652e35cf81dSBarry Smith #undef __FUNCT__ 2653e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2654e35cf81dSBarry Smith /*@ 2655e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2656e35cf81dSBarry Smith 26573f9fe445SBarry Smith Not Collective 2658e35cf81dSBarry Smith 2659e35cf81dSBarry Smith Input Parameter: 2660e35cf81dSBarry Smith . snes - the SNES context 2661e35cf81dSBarry Smith 2662e35cf81dSBarry Smith Output Parameter: 2663e35cf81dSBarry 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 2664e35cf81dSBarry Smith the Jacobian is built etc. 2665e35cf81dSBarry Smith 2666e35cf81dSBarry Smith Options Database Keys: 2667e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2668e35cf81dSBarry Smith 2669e35cf81dSBarry Smith Notes: 2670e35cf81dSBarry Smith The default is 1 2671e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2672e35cf81dSBarry Smith 2673e35cf81dSBarry Smith Level: intermediate 2674e35cf81dSBarry Smith 2675e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2676e35cf81dSBarry Smith 2677e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2678e35cf81dSBarry Smith 2679e35cf81dSBarry Smith @*/ 26807087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2681e35cf81dSBarry Smith { 2682e35cf81dSBarry Smith PetscFunctionBegin; 26830700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2684e35cf81dSBarry Smith *lag = snes->lagjacobian; 2685e35cf81dSBarry Smith PetscFunctionReturn(0); 2686e35cf81dSBarry Smith } 2687e35cf81dSBarry Smith 2688e35cf81dSBarry Smith #undef __FUNCT__ 26894a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 26909b94acceSBarry Smith /*@ 2691d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 26929b94acceSBarry Smith 26933f9fe445SBarry Smith Logically Collective on SNES 2694c7afd0dbSLois Curfman McInnes 26959b94acceSBarry Smith Input Parameters: 2696c7afd0dbSLois Curfman McInnes + snes - the SNES context 269770441072SBarry Smith . abstol - absolute convergence tolerance 269833174efeSLois Curfman McInnes . rtol - relative convergence tolerance 269933174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 270033174efeSLois Curfman McInnes of the change in the solution between steps 270133174efeSLois Curfman McInnes . maxit - maximum number of iterations 2702c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2703fee21e36SBarry Smith 270433174efeSLois Curfman McInnes Options Database Keys: 270570441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2706c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2707c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2708c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2709c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 27109b94acceSBarry Smith 2711d7a720efSLois Curfman McInnes Notes: 27129b94acceSBarry Smith The default maximum number of iterations is 50. 27139b94acceSBarry Smith The default maximum number of function evaluations is 1000. 27149b94acceSBarry Smith 271536851e7fSLois Curfman McInnes Level: intermediate 271636851e7fSLois Curfman McInnes 271733174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 27189b94acceSBarry Smith 27192492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 27209b94acceSBarry Smith @*/ 27217087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 27229b94acceSBarry Smith { 27233a40ed3dSBarry Smith PetscFunctionBegin; 27240700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2725c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2726c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2727c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2728c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2729c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2730c5eb9154SBarry Smith 2731ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2732ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2733ab54825eSJed Brown snes->abstol = abstol; 2734ab54825eSJed Brown } 2735ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2736ab54825eSJed 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); 2737ab54825eSJed Brown snes->rtol = rtol; 2738ab54825eSJed Brown } 2739ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2740ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2741c60f73f4SPeter Brune snes->stol = stol; 2742ab54825eSJed Brown } 2743ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2744ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2745ab54825eSJed Brown snes->max_its = maxit; 2746ab54825eSJed Brown } 2747ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2748ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2749ab54825eSJed Brown snes->max_funcs = maxf; 2750ab54825eSJed Brown } 275188976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 27523a40ed3dSBarry Smith PetscFunctionReturn(0); 27539b94acceSBarry Smith } 27549b94acceSBarry Smith 27554a2ae208SSatish Balay #undef __FUNCT__ 27564a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 27579b94acceSBarry Smith /*@ 275833174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 275933174efeSLois Curfman McInnes 2760c7afd0dbSLois Curfman McInnes Not Collective 2761c7afd0dbSLois Curfman McInnes 276233174efeSLois Curfman McInnes Input Parameters: 2763c7afd0dbSLois Curfman McInnes + snes - the SNES context 276485385478SLisandro Dalcin . atol - absolute convergence tolerance 276533174efeSLois Curfman McInnes . rtol - relative convergence tolerance 276633174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 276733174efeSLois Curfman McInnes of the change in the solution between steps 276833174efeSLois Curfman McInnes . maxit - maximum number of iterations 2769c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2770fee21e36SBarry Smith 277133174efeSLois Curfman McInnes Notes: 277233174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 277333174efeSLois Curfman McInnes 277436851e7fSLois Curfman McInnes Level: intermediate 277536851e7fSLois Curfman McInnes 277633174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 277733174efeSLois Curfman McInnes 277833174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 277933174efeSLois Curfman McInnes @*/ 27807087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 278133174efeSLois Curfman McInnes { 27823a40ed3dSBarry Smith PetscFunctionBegin; 27830700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 278485385478SLisandro Dalcin if (atol) *atol = snes->abstol; 278533174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 2786c60f73f4SPeter Brune if (stol) *stol = snes->stol; 278733174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 278833174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 27893a40ed3dSBarry Smith PetscFunctionReturn(0); 279033174efeSLois Curfman McInnes } 279133174efeSLois Curfman McInnes 27924a2ae208SSatish Balay #undef __FUNCT__ 27934a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 279433174efeSLois Curfman McInnes /*@ 27959b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 27969b94acceSBarry Smith 27973f9fe445SBarry Smith Logically Collective on SNES 2798fee21e36SBarry Smith 2799c7afd0dbSLois Curfman McInnes Input Parameters: 2800c7afd0dbSLois Curfman McInnes + snes - the SNES context 2801c7afd0dbSLois Curfman McInnes - tol - tolerance 2802c7afd0dbSLois Curfman McInnes 28039b94acceSBarry Smith Options Database Key: 2804c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 28059b94acceSBarry Smith 280636851e7fSLois Curfman McInnes Level: intermediate 280736851e7fSLois Curfman McInnes 28089b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 28099b94acceSBarry Smith 28102492ecdbSBarry Smith .seealso: SNESSetTolerances() 28119b94acceSBarry Smith @*/ 28127087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 28139b94acceSBarry Smith { 28143a40ed3dSBarry Smith PetscFunctionBegin; 28150700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2816c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 28179b94acceSBarry Smith snes->deltatol = tol; 28183a40ed3dSBarry Smith PetscFunctionReturn(0); 28199b94acceSBarry Smith } 28209b94acceSBarry Smith 2821df9fa365SBarry Smith /* 2822df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2823df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2824df9fa365SBarry Smith macros instead of functions 2825df9fa365SBarry Smith */ 28264a2ae208SSatish Balay #undef __FUNCT__ 2827a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 28287087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2829ce1608b8SBarry Smith { 2830dfbe8321SBarry Smith PetscErrorCode ierr; 2831ce1608b8SBarry Smith 2832ce1608b8SBarry Smith PetscFunctionBegin; 28330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2834a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2835ce1608b8SBarry Smith PetscFunctionReturn(0); 2836ce1608b8SBarry Smith } 2837ce1608b8SBarry Smith 28384a2ae208SSatish Balay #undef __FUNCT__ 2839a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 28407087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2841df9fa365SBarry Smith { 2842dfbe8321SBarry Smith PetscErrorCode ierr; 2843df9fa365SBarry Smith 2844df9fa365SBarry Smith PetscFunctionBegin; 2845a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2846df9fa365SBarry Smith PetscFunctionReturn(0); 2847df9fa365SBarry Smith } 2848df9fa365SBarry Smith 28494a2ae208SSatish Balay #undef __FUNCT__ 2850a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 28516bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2852df9fa365SBarry Smith { 2853dfbe8321SBarry Smith PetscErrorCode ierr; 2854df9fa365SBarry Smith 2855df9fa365SBarry Smith PetscFunctionBegin; 2856a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2857df9fa365SBarry Smith PetscFunctionReturn(0); 2858df9fa365SBarry Smith } 2859df9fa365SBarry Smith 28607087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2861b271bb04SBarry Smith #undef __FUNCT__ 2862b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 28637087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2864b271bb04SBarry Smith { 2865b271bb04SBarry Smith PetscDrawLG lg; 2866b271bb04SBarry Smith PetscErrorCode ierr; 2867b271bb04SBarry Smith PetscReal x,y,per; 2868b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2869b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2870b271bb04SBarry Smith PetscDraw draw; 2871b271bb04SBarry Smith PetscFunctionBegin; 2872b271bb04SBarry Smith if (!monctx) { 2873b271bb04SBarry Smith MPI_Comm comm; 2874b271bb04SBarry Smith 2875b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2876b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2877b271bb04SBarry Smith } 2878b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2879b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2880b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2881b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2882b271bb04SBarry Smith x = (PetscReal) n; 2883b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2884b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2885b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2886b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2887b271bb04SBarry Smith } 2888b271bb04SBarry Smith 2889b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2890b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2891b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2892b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2893b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2894b271bb04SBarry Smith x = (PetscReal) n; 2895b271bb04SBarry Smith y = 100.0*per; 2896b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2897b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2898b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2899b271bb04SBarry Smith } 2900b271bb04SBarry Smith 2901b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2902b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2903b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2904b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2905b271bb04SBarry Smith x = (PetscReal) n; 2906b271bb04SBarry Smith y = (prev - rnorm)/prev; 2907b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2908b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2909b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2910b271bb04SBarry Smith } 2911b271bb04SBarry Smith 2912b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2913b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2914b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2915b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2916b271bb04SBarry Smith x = (PetscReal) n; 2917b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2918b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2919b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2920b271bb04SBarry Smith } 2921b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2922b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2923b271bb04SBarry Smith } 2924b271bb04SBarry Smith prev = rnorm; 2925b271bb04SBarry Smith PetscFunctionReturn(0); 2926b271bb04SBarry Smith } 2927b271bb04SBarry Smith 2928b271bb04SBarry Smith #undef __FUNCT__ 2929b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 29307087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2931b271bb04SBarry Smith { 2932b271bb04SBarry Smith PetscErrorCode ierr; 2933b271bb04SBarry Smith 2934b271bb04SBarry Smith PetscFunctionBegin; 2935b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2936b271bb04SBarry Smith PetscFunctionReturn(0); 2937b271bb04SBarry Smith } 2938b271bb04SBarry Smith 2939b271bb04SBarry Smith #undef __FUNCT__ 2940b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 29416bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2942b271bb04SBarry Smith { 2943b271bb04SBarry Smith PetscErrorCode ierr; 2944b271bb04SBarry Smith 2945b271bb04SBarry Smith PetscFunctionBegin; 2946b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2947b271bb04SBarry Smith PetscFunctionReturn(0); 2948b271bb04SBarry Smith } 2949b271bb04SBarry Smith 29507a03ce2fSLisandro Dalcin #undef __FUNCT__ 29517a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 2952228d79bcSJed Brown /*@ 2953228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 2954228d79bcSJed Brown 2955228d79bcSJed Brown Collective on SNES 2956228d79bcSJed Brown 2957228d79bcSJed Brown Input Parameters: 2958228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 2959228d79bcSJed Brown . iter - iteration number 2960228d79bcSJed Brown - rnorm - relative norm of the residual 2961228d79bcSJed Brown 2962228d79bcSJed Brown Notes: 2963228d79bcSJed Brown This routine is called by the SNES implementations. 2964228d79bcSJed Brown It does not typically need to be called by the user. 2965228d79bcSJed Brown 2966228d79bcSJed Brown Level: developer 2967228d79bcSJed Brown 2968228d79bcSJed Brown .seealso: SNESMonitorSet() 2969228d79bcSJed Brown @*/ 29707a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 29717a03ce2fSLisandro Dalcin { 29727a03ce2fSLisandro Dalcin PetscErrorCode ierr; 29737a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 29747a03ce2fSLisandro Dalcin 29757a03ce2fSLisandro Dalcin PetscFunctionBegin; 29767a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 29777a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 29787a03ce2fSLisandro Dalcin } 29797a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 29807a03ce2fSLisandro Dalcin } 29817a03ce2fSLisandro Dalcin 29829b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 29839b94acceSBarry Smith 29844a2ae208SSatish Balay #undef __FUNCT__ 2985a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 29869b94acceSBarry Smith /*@C 2987a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 29889b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 29899b94acceSBarry Smith progress. 29909b94acceSBarry Smith 29913f9fe445SBarry Smith Logically Collective on SNES 2992fee21e36SBarry Smith 2993c7afd0dbSLois Curfman McInnes Input Parameters: 2994c7afd0dbSLois Curfman McInnes + snes - the SNES context 2995c7afd0dbSLois Curfman McInnes . func - monitoring routine 2996b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 2997e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 2998b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 2999b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 30009b94acceSBarry Smith 3001c7afd0dbSLois Curfman McInnes Calling sequence of func: 3002a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 3003c7afd0dbSLois Curfman McInnes 3004c7afd0dbSLois Curfman McInnes + snes - the SNES context 3005c7afd0dbSLois Curfman McInnes . its - iteration number 3006c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 300740a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 30089b94acceSBarry Smith 30099665c990SLois Curfman McInnes Options Database Keys: 3010a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 3011a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 3012a6570f20SBarry Smith uses SNESMonitorLGCreate() 3013cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 3014c7afd0dbSLois Curfman McInnes been hardwired into a code by 3015a6570f20SBarry Smith calls to SNESMonitorSet(), but 3016c7afd0dbSLois Curfman McInnes does not cancel those set via 3017c7afd0dbSLois Curfman McInnes the options database. 30189665c990SLois Curfman McInnes 3019639f9d9dSBarry Smith Notes: 30206bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 3021a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 30226bc08f3fSLois Curfman McInnes order in which they were set. 3023639f9d9dSBarry Smith 3024025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 3025025f1a04SBarry Smith 302636851e7fSLois Curfman McInnes Level: intermediate 302736851e7fSLois Curfman McInnes 30289b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 30299b94acceSBarry Smith 3030a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 30319b94acceSBarry Smith @*/ 3032c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 30339b94acceSBarry Smith { 3034b90d0a6eSBarry Smith PetscInt i; 3035649052a6SBarry Smith PetscErrorCode ierr; 3036b90d0a6eSBarry Smith 30373a40ed3dSBarry Smith PetscFunctionBegin; 30380700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 303917186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 3040b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 3041649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 3042649052a6SBarry Smith if (monitordestroy) { 3043c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 3044649052a6SBarry Smith } 3045b90d0a6eSBarry Smith PetscFunctionReturn(0); 3046b90d0a6eSBarry Smith } 3047b90d0a6eSBarry Smith } 3048b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 3049b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 3050639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 30513a40ed3dSBarry Smith PetscFunctionReturn(0); 30529b94acceSBarry Smith } 30539b94acceSBarry Smith 30544a2ae208SSatish Balay #undef __FUNCT__ 3055a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 30565cd90555SBarry Smith /*@C 3057a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 30585cd90555SBarry Smith 30593f9fe445SBarry Smith Logically Collective on SNES 3060c7afd0dbSLois Curfman McInnes 30615cd90555SBarry Smith Input Parameters: 30625cd90555SBarry Smith . snes - the SNES context 30635cd90555SBarry Smith 30641a480d89SAdministrator Options Database Key: 3065a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 3066a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 3067c7afd0dbSLois Curfman McInnes set via the options database 30685cd90555SBarry Smith 30695cd90555SBarry Smith Notes: 30705cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 30715cd90555SBarry Smith 307236851e7fSLois Curfman McInnes Level: intermediate 307336851e7fSLois Curfman McInnes 30745cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 30755cd90555SBarry Smith 3076a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 30775cd90555SBarry Smith @*/ 30787087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 30795cd90555SBarry Smith { 3080d952e501SBarry Smith PetscErrorCode ierr; 3081d952e501SBarry Smith PetscInt i; 3082d952e501SBarry Smith 30835cd90555SBarry Smith PetscFunctionBegin; 30840700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3085d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 3086d952e501SBarry Smith if (snes->monitordestroy[i]) { 30873c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 3088d952e501SBarry Smith } 3089d952e501SBarry Smith } 30905cd90555SBarry Smith snes->numbermonitors = 0; 30915cd90555SBarry Smith PetscFunctionReturn(0); 30925cd90555SBarry Smith } 30935cd90555SBarry Smith 30944a2ae208SSatish Balay #undef __FUNCT__ 30954a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 30969b94acceSBarry Smith /*@C 30979b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 30989b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 30999b94acceSBarry Smith 31003f9fe445SBarry Smith Logically Collective on SNES 3101fee21e36SBarry Smith 3102c7afd0dbSLois Curfman McInnes Input Parameters: 3103c7afd0dbSLois Curfman McInnes + snes - the SNES context 3104c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 31057f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 31067f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 31079b94acceSBarry Smith 3108c7afd0dbSLois Curfman McInnes Calling sequence of func: 310906ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 3110c7afd0dbSLois Curfman McInnes 3111c7afd0dbSLois Curfman McInnes + snes - the SNES context 311206ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 3113c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 3114184914b5SBarry Smith . reason - reason for convergence/divergence 3115c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 31164b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 31174b27c08aSLois Curfman McInnes - f - 2-norm of function 31189b94acceSBarry Smith 311936851e7fSLois Curfman McInnes Level: advanced 312036851e7fSLois Curfman McInnes 31219b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 31229b94acceSBarry Smith 312385385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 31249b94acceSBarry Smith @*/ 31257087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 31269b94acceSBarry Smith { 31277f7931b9SBarry Smith PetscErrorCode ierr; 31287f7931b9SBarry Smith 31293a40ed3dSBarry Smith PetscFunctionBegin; 31300700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 313185385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 31327f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 31337f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 31347f7931b9SBarry Smith } 313585385478SLisandro Dalcin snes->ops->converged = func; 31367f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 313785385478SLisandro Dalcin snes->cnvP = cctx; 31383a40ed3dSBarry Smith PetscFunctionReturn(0); 31399b94acceSBarry Smith } 31409b94acceSBarry Smith 31414a2ae208SSatish Balay #undef __FUNCT__ 31424a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 314352baeb72SSatish Balay /*@ 3144184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 3145184914b5SBarry Smith 3146184914b5SBarry Smith Not Collective 3147184914b5SBarry Smith 3148184914b5SBarry Smith Input Parameter: 3149184914b5SBarry Smith . snes - the SNES context 3150184914b5SBarry Smith 3151184914b5SBarry Smith Output Parameter: 31524d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 3153184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 3154184914b5SBarry Smith 3155184914b5SBarry Smith Level: intermediate 3156184914b5SBarry Smith 3157184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 3158184914b5SBarry Smith 3159184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 3160184914b5SBarry Smith 316185385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 3162184914b5SBarry Smith @*/ 31637087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 3164184914b5SBarry Smith { 3165184914b5SBarry Smith PetscFunctionBegin; 31660700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31674482741eSBarry Smith PetscValidPointer(reason,2); 3168184914b5SBarry Smith *reason = snes->reason; 3169184914b5SBarry Smith PetscFunctionReturn(0); 3170184914b5SBarry Smith } 3171184914b5SBarry Smith 31724a2ae208SSatish Balay #undef __FUNCT__ 31734a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 3174c9005455SLois Curfman McInnes /*@ 3175c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 3176c9005455SLois Curfman McInnes 31773f9fe445SBarry Smith Logically Collective on SNES 3178fee21e36SBarry Smith 3179c7afd0dbSLois Curfman McInnes Input Parameters: 3180c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 31818c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 3182cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 3183758f92a0SBarry Smith . na - size of a and its 318464731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 3185758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 3186c7afd0dbSLois Curfman McInnes 3187308dcc3eSBarry Smith Notes: 3188308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 3189308dcc3eSBarry Smith default array of length 10000 is allocated. 3190308dcc3eSBarry Smith 3191c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 3192c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 3193c9005455SLois Curfman McInnes during the section of code that is being timed. 3194c9005455SLois Curfman McInnes 319536851e7fSLois Curfman McInnes Level: intermediate 319636851e7fSLois Curfman McInnes 3197c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 3198758f92a0SBarry Smith 319908405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 3200758f92a0SBarry Smith 3201c9005455SLois Curfman McInnes @*/ 32027087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 3203c9005455SLois Curfman McInnes { 3204308dcc3eSBarry Smith PetscErrorCode ierr; 3205308dcc3eSBarry Smith 32063a40ed3dSBarry Smith PetscFunctionBegin; 32070700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 32084482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 3209a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 3210308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 3211308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 3212308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 3213308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 3214308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 3215308dcc3eSBarry Smith } 3216c9005455SLois Curfman McInnes snes->conv_hist = a; 3217758f92a0SBarry Smith snes->conv_hist_its = its; 3218758f92a0SBarry Smith snes->conv_hist_max = na; 3219a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 3220758f92a0SBarry Smith snes->conv_hist_reset = reset; 3221758f92a0SBarry Smith PetscFunctionReturn(0); 3222758f92a0SBarry Smith } 3223758f92a0SBarry Smith 3224308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3225c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 3226c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 3227308dcc3eSBarry Smith EXTERN_C_BEGIN 3228308dcc3eSBarry Smith #undef __FUNCT__ 3229308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 3230308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3231308dcc3eSBarry Smith { 3232308dcc3eSBarry Smith mxArray *mat; 3233308dcc3eSBarry Smith PetscInt i; 3234308dcc3eSBarry Smith PetscReal *ar; 3235308dcc3eSBarry Smith 3236308dcc3eSBarry Smith PetscFunctionBegin; 3237308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3238308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3239308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 3240308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 3241308dcc3eSBarry Smith } 3242308dcc3eSBarry Smith PetscFunctionReturn(mat); 3243308dcc3eSBarry Smith } 3244308dcc3eSBarry Smith EXTERN_C_END 3245308dcc3eSBarry Smith #endif 3246308dcc3eSBarry Smith 3247308dcc3eSBarry Smith 32484a2ae208SSatish Balay #undef __FUNCT__ 32494a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 32500c4c9dddSBarry Smith /*@C 3251758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3252758f92a0SBarry Smith 32533f9fe445SBarry Smith Not Collective 3254758f92a0SBarry Smith 3255758f92a0SBarry Smith Input Parameter: 3256758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3257758f92a0SBarry Smith 3258758f92a0SBarry Smith Output Parameters: 3259758f92a0SBarry Smith . a - array to hold history 3260758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3261758f92a0SBarry Smith negative if not converged) for each solve. 3262758f92a0SBarry Smith - na - size of a and its 3263758f92a0SBarry Smith 3264758f92a0SBarry Smith Notes: 3265758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3266758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3267758f92a0SBarry Smith 3268758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3269758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3270758f92a0SBarry Smith during the section of code that is being timed. 3271758f92a0SBarry Smith 3272758f92a0SBarry Smith Level: intermediate 3273758f92a0SBarry Smith 3274758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3275758f92a0SBarry Smith 3276758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3277758f92a0SBarry Smith 3278758f92a0SBarry Smith @*/ 32797087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3280758f92a0SBarry Smith { 3281758f92a0SBarry Smith PetscFunctionBegin; 32820700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3283758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3284758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3285758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 32863a40ed3dSBarry Smith PetscFunctionReturn(0); 3287c9005455SLois Curfman McInnes } 3288c9005455SLois Curfman McInnes 3289e74ef692SMatthew Knepley #undef __FUNCT__ 3290e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 3291ac226902SBarry Smith /*@C 329276b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3293eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 32947e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 329576b2cf59SMatthew Knepley 32963f9fe445SBarry Smith Logically Collective on SNES 329776b2cf59SMatthew Knepley 329876b2cf59SMatthew Knepley Input Parameters: 329976b2cf59SMatthew Knepley . snes - The nonlinear solver context 330076b2cf59SMatthew Knepley . func - The function 330176b2cf59SMatthew Knepley 330276b2cf59SMatthew Knepley Calling sequence of func: 3303b5d30489SBarry Smith . func (SNES snes, PetscInt step); 330476b2cf59SMatthew Knepley 330576b2cf59SMatthew Knepley . step - The current step of the iteration 330676b2cf59SMatthew Knepley 3307fe97e370SBarry Smith Level: advanced 3308fe97e370SBarry Smith 3309fe97e370SBarry 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() 3310fe97e370SBarry Smith This is not used by most users. 331176b2cf59SMatthew Knepley 331276b2cf59SMatthew Knepley .keywords: SNES, update 3313b5d30489SBarry Smith 331485385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 331576b2cf59SMatthew Knepley @*/ 33167087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 331776b2cf59SMatthew Knepley { 331876b2cf59SMatthew Knepley PetscFunctionBegin; 33190700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3320e7788613SBarry Smith snes->ops->update = func; 332176b2cf59SMatthew Knepley PetscFunctionReturn(0); 332276b2cf59SMatthew Knepley } 332376b2cf59SMatthew Knepley 3324e74ef692SMatthew Knepley #undef __FUNCT__ 3325e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 332676b2cf59SMatthew Knepley /*@ 332776b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 332876b2cf59SMatthew Knepley 332976b2cf59SMatthew Knepley Not collective 333076b2cf59SMatthew Knepley 333176b2cf59SMatthew Knepley Input Parameters: 333276b2cf59SMatthew Knepley . snes - The nonlinear solver context 333376b2cf59SMatthew Knepley . step - The current step of the iteration 333476b2cf59SMatthew Knepley 3335205452f4SMatthew Knepley Level: intermediate 3336205452f4SMatthew Knepley 333776b2cf59SMatthew Knepley .keywords: SNES, update 3338a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 333976b2cf59SMatthew Knepley @*/ 33407087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 334176b2cf59SMatthew Knepley { 334276b2cf59SMatthew Knepley PetscFunctionBegin; 334376b2cf59SMatthew Knepley PetscFunctionReturn(0); 334476b2cf59SMatthew Knepley } 334576b2cf59SMatthew Knepley 33464a2ae208SSatish Balay #undef __FUNCT__ 33474a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 33489b94acceSBarry Smith /* 33499b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 33509b94acceSBarry Smith positive parameter delta. 33519b94acceSBarry Smith 33529b94acceSBarry Smith Input Parameters: 3353c7afd0dbSLois Curfman McInnes + snes - the SNES context 33549b94acceSBarry Smith . y - approximate solution of linear system 33559b94acceSBarry Smith . fnorm - 2-norm of current function 3356c7afd0dbSLois Curfman McInnes - delta - trust region size 33579b94acceSBarry Smith 33589b94acceSBarry Smith Output Parameters: 3359c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 33609b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 33619b94acceSBarry Smith region, and exceeds zero otherwise. 3362c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 33639b94acceSBarry Smith 33649b94acceSBarry Smith Note: 33654b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 33669b94acceSBarry Smith is set to be the maximum allowable step size. 33679b94acceSBarry Smith 33689b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 33699b94acceSBarry Smith */ 3370dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 33719b94acceSBarry Smith { 3372064f8208SBarry Smith PetscReal nrm; 3373ea709b57SSatish Balay PetscScalar cnorm; 3374dfbe8321SBarry Smith PetscErrorCode ierr; 33753a40ed3dSBarry Smith 33763a40ed3dSBarry Smith PetscFunctionBegin; 33770700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 33780700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3379c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3380184914b5SBarry Smith 3381064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3382064f8208SBarry Smith if (nrm > *delta) { 3383064f8208SBarry Smith nrm = *delta/nrm; 3384064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3385064f8208SBarry Smith cnorm = nrm; 33862dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 33879b94acceSBarry Smith *ynorm = *delta; 33889b94acceSBarry Smith } else { 33899b94acceSBarry Smith *gpnorm = 0.0; 3390064f8208SBarry Smith *ynorm = nrm; 33919b94acceSBarry Smith } 33923a40ed3dSBarry Smith PetscFunctionReturn(0); 33939b94acceSBarry Smith } 33949b94acceSBarry Smith 33954a2ae208SSatish Balay #undef __FUNCT__ 33964a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 33976ce558aeSBarry Smith /*@C 3398f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3399f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 34009b94acceSBarry Smith 3401c7afd0dbSLois Curfman McInnes Collective on SNES 3402c7afd0dbSLois Curfman McInnes 3403b2002411SLois Curfman McInnes Input Parameters: 3404c7afd0dbSLois Curfman McInnes + snes - the SNES context 34053cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 340685385478SLisandro Dalcin - x - the solution vector. 34079b94acceSBarry Smith 3408b2002411SLois Curfman McInnes Notes: 34098ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 34108ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 34118ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 34128ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 34138ddd3da0SLois Curfman McInnes 341436851e7fSLois Curfman McInnes Level: beginner 341536851e7fSLois Curfman McInnes 34169b94acceSBarry Smith .keywords: SNES, nonlinear, solve 34179b94acceSBarry Smith 3418c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 34199b94acceSBarry Smith @*/ 34207087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 34219b94acceSBarry Smith { 3422dfbe8321SBarry Smith PetscErrorCode ierr; 3423ace3abfcSBarry Smith PetscBool flg; 3424eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 3425eabae89aSBarry Smith PetscViewer viewer; 3426efd51863SBarry Smith PetscInt grid; 3427a69afd8bSBarry Smith Vec xcreated = PETSC_NULL; 3428caa4e7f2SJed Brown DM dm; 3429052efed2SBarry Smith 34303a40ed3dSBarry Smith PetscFunctionBegin; 34310700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3432a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3433a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 34340700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 343585385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 343685385478SLisandro Dalcin 3437caa4e7f2SJed Brown if (!x) { 3438caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3439caa4e7f2SJed Brown ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 3440a69afd8bSBarry Smith x = xcreated; 3441a69afd8bSBarry Smith } 3442a69afd8bSBarry Smith 3443a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3444efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3445efd51863SBarry Smith 344685385478SLisandro Dalcin /* set solution vector */ 3447efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 34486bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 344985385478SLisandro Dalcin snes->vec_sol = x; 3450caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3451caa4e7f2SJed Brown 3452caa4e7f2SJed Brown /* set affine vector if provided */ 345385385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 34546bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 345585385478SLisandro Dalcin snes->vec_rhs = b; 345685385478SLisandro Dalcin 345770e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 34583f149594SLisandro Dalcin 34597eee914bSBarry Smith if (!grid) { 34607eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3461d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3462dd568438SSatish Balay } else if (snes->dm) { 3463dd568438SSatish Balay PetscBool ig; 3464dd568438SSatish Balay ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr); 3465dd568438SSatish Balay if (ig) { 34667eee914bSBarry Smith ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr); 34677eee914bSBarry Smith } 3468d25893d9SBarry Smith } 3469dd568438SSatish Balay } 3470d25893d9SBarry Smith 3471abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 347250ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3473d5e45103SBarry Smith 34743f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 34754936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 347685385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 34774936397dSBarry Smith if (snes->domainerror){ 34784936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 34794936397dSBarry Smith snes->domainerror = PETSC_FALSE; 34804936397dSBarry Smith } 348117186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 34823f149594SLisandro Dalcin 34837adad957SLisandro Dalcin ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 3484eabae89aSBarry Smith if (flg && !PetscPreLoadingOn) { 34857adad957SLisandro Dalcin ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 3486eabae89aSBarry Smith ierr = SNESView(snes,viewer);CHKERRQ(ierr); 34876bf464f9SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3488eabae89aSBarry Smith } 3489eabae89aSBarry Smith 349090d69ab7SBarry Smith flg = PETSC_FALSE; 3491acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3492da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 34935968eb51SBarry Smith if (snes->printreason) { 3494a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 34955968eb51SBarry Smith if (snes->reason > 0) { 3496c7e7b494SJed Brown ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 34975968eb51SBarry Smith } else { 3498c7e7b494SJed Brown ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 34995968eb51SBarry Smith } 3500a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 35015968eb51SBarry Smith } 35025968eb51SBarry Smith 35038501fc72SJed Brown flg = PETSC_FALSE; 35048501fc72SJed Brown ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 35058501fc72SJed Brown if (flg) { 35068501fc72SJed Brown PetscViewer viewer; 35078501fc72SJed Brown ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 35088501fc72SJed Brown ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 35098501fc72SJed Brown ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 35108501fc72SJed Brown ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 35118501fc72SJed Brown ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 35128501fc72SJed Brown } 35138501fc72SJed Brown 3514e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3515efd51863SBarry Smith if (grid < snes->gridsequence) { 3516efd51863SBarry Smith DM fine; 3517efd51863SBarry Smith Vec xnew; 3518efd51863SBarry Smith Mat interp; 3519efd51863SBarry Smith 3520efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3521c5c77316SJed Brown if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 3522e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3523efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3524efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3525c833c3b5SJed Brown ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr); 3526efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3527efd51863SBarry Smith x = xnew; 3528efd51863SBarry Smith 3529efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3530efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3531efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3532a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3533efd51863SBarry Smith } 3534efd51863SBarry Smith } 3535a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 35363a40ed3dSBarry Smith PetscFunctionReturn(0); 35379b94acceSBarry Smith } 35389b94acceSBarry Smith 35399b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 35409b94acceSBarry Smith 35414a2ae208SSatish Balay #undef __FUNCT__ 35424a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 354382bf6240SBarry Smith /*@C 35444b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 35459b94acceSBarry Smith 3546fee21e36SBarry Smith Collective on SNES 3547fee21e36SBarry Smith 3548c7afd0dbSLois Curfman McInnes Input Parameters: 3549c7afd0dbSLois Curfman McInnes + snes - the SNES context 3550454a90a3SBarry Smith - type - a known method 3551c7afd0dbSLois Curfman McInnes 3552c7afd0dbSLois Curfman McInnes Options Database Key: 3553454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3554c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3555ae12b187SLois Curfman McInnes 35569b94acceSBarry Smith Notes: 3557e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 35584b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3559c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 35604b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3561c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 35629b94acceSBarry Smith 3563ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3564ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3565ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3566ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3567ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3568ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3569ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3570ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3571ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3572b0a32e0cSBarry Smith appropriate method. 357336851e7fSLois Curfman McInnes 357436851e7fSLois Curfman McInnes Level: intermediate 3575a703fe33SLois Curfman McInnes 3576454a90a3SBarry Smith .keywords: SNES, set, type 3577435da068SBarry Smith 3578435da068SBarry Smith .seealso: SNESType, SNESCreate() 3579435da068SBarry Smith 35809b94acceSBarry Smith @*/ 35817087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 35829b94acceSBarry Smith { 3583dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3584ace3abfcSBarry Smith PetscBool match; 35853a40ed3dSBarry Smith 35863a40ed3dSBarry Smith PetscFunctionBegin; 35870700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35884482741eSBarry Smith PetscValidCharPointer(type,2); 358982bf6240SBarry Smith 3590251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 35910f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 359292ff6ae8SBarry Smith 35934b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3594e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 359575396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 3596b5c23020SJed Brown if (snes->ops->destroy) { 3597b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 3598b5c23020SJed Brown snes->ops->destroy = PETSC_NULL; 3599b5c23020SJed Brown } 360075396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 360175396ef9SLisandro Dalcin snes->ops->setup = 0; 360275396ef9SLisandro Dalcin snes->ops->solve = 0; 360375396ef9SLisandro Dalcin snes->ops->view = 0; 360475396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 360575396ef9SLisandro Dalcin snes->ops->destroy = 0; 360675396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 360775396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3608454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 360903bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 36109fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 36119fb22e1aSBarry Smith if (PetscAMSPublishAll) { 36129fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 36139fb22e1aSBarry Smith } 36149fb22e1aSBarry Smith #endif 36153a40ed3dSBarry Smith PetscFunctionReturn(0); 36169b94acceSBarry Smith } 36179b94acceSBarry Smith 3618a847f771SSatish Balay 36199b94acceSBarry Smith /* --------------------------------------------------------------------- */ 36204a2ae208SSatish Balay #undef __FUNCT__ 36214a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 362252baeb72SSatish Balay /*@ 36239b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3624f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 36259b94acceSBarry Smith 3626fee21e36SBarry Smith Not Collective 3627fee21e36SBarry Smith 362836851e7fSLois Curfman McInnes Level: advanced 362936851e7fSLois Curfman McInnes 36309b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 36319b94acceSBarry Smith 36329b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 36339b94acceSBarry Smith @*/ 36347087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 36359b94acceSBarry Smith { 3636dfbe8321SBarry Smith PetscErrorCode ierr; 363782bf6240SBarry Smith 36383a40ed3dSBarry Smith PetscFunctionBegin; 36391441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 36404c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 36413a40ed3dSBarry Smith PetscFunctionReturn(0); 36429b94acceSBarry Smith } 36439b94acceSBarry Smith 36444a2ae208SSatish Balay #undef __FUNCT__ 36454a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 36469b94acceSBarry Smith /*@C 36479a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 36489b94acceSBarry Smith 3649c7afd0dbSLois Curfman McInnes Not Collective 3650c7afd0dbSLois Curfman McInnes 36519b94acceSBarry Smith Input Parameter: 36524b0e389bSBarry Smith . snes - nonlinear solver context 36539b94acceSBarry Smith 36549b94acceSBarry Smith Output Parameter: 36553a7fca6bSBarry Smith . type - SNES method (a character string) 36569b94acceSBarry Smith 365736851e7fSLois Curfman McInnes Level: intermediate 365836851e7fSLois Curfman McInnes 3659454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 36609b94acceSBarry Smith @*/ 36617087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 36629b94acceSBarry Smith { 36633a40ed3dSBarry Smith PetscFunctionBegin; 36640700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36654482741eSBarry Smith PetscValidPointer(type,2); 36667adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 36673a40ed3dSBarry Smith PetscFunctionReturn(0); 36689b94acceSBarry Smith } 36699b94acceSBarry Smith 36704a2ae208SSatish Balay #undef __FUNCT__ 36714a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 367252baeb72SSatish Balay /*@ 36739b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3674c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 36759b94acceSBarry Smith 3676c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3677c7afd0dbSLois Curfman McInnes 36789b94acceSBarry Smith Input Parameter: 36799b94acceSBarry Smith . snes - the SNES context 36809b94acceSBarry Smith 36819b94acceSBarry Smith Output Parameter: 36829b94acceSBarry Smith . x - the solution 36839b94acceSBarry Smith 368470e92668SMatthew Knepley Level: intermediate 368536851e7fSLois Curfman McInnes 36869b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 36879b94acceSBarry Smith 368885385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 36899b94acceSBarry Smith @*/ 36907087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 36919b94acceSBarry Smith { 36923a40ed3dSBarry Smith PetscFunctionBegin; 36930700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36944482741eSBarry Smith PetscValidPointer(x,2); 369585385478SLisandro Dalcin *x = snes->vec_sol; 369670e92668SMatthew Knepley PetscFunctionReturn(0); 369770e92668SMatthew Knepley } 369870e92668SMatthew Knepley 369970e92668SMatthew Knepley #undef __FUNCT__ 37004a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 370152baeb72SSatish Balay /*@ 37029b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 37039b94acceSBarry Smith stored. 37049b94acceSBarry Smith 3705c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3706c7afd0dbSLois Curfman McInnes 37079b94acceSBarry Smith Input Parameter: 37089b94acceSBarry Smith . snes - the SNES context 37099b94acceSBarry Smith 37109b94acceSBarry Smith Output Parameter: 37119b94acceSBarry Smith . x - the solution update 37129b94acceSBarry Smith 371336851e7fSLois Curfman McInnes Level: advanced 371436851e7fSLois Curfman McInnes 37159b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 37169b94acceSBarry Smith 371785385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 37189b94acceSBarry Smith @*/ 37197087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 37209b94acceSBarry Smith { 37213a40ed3dSBarry Smith PetscFunctionBegin; 37220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37234482741eSBarry Smith PetscValidPointer(x,2); 372485385478SLisandro Dalcin *x = snes->vec_sol_update; 37253a40ed3dSBarry Smith PetscFunctionReturn(0); 37269b94acceSBarry Smith } 37279b94acceSBarry Smith 37284a2ae208SSatish Balay #undef __FUNCT__ 37294a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 37309b94acceSBarry Smith /*@C 37313638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 37329b94acceSBarry Smith 3733a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 3734c7afd0dbSLois Curfman McInnes 37359b94acceSBarry Smith Input Parameter: 37369b94acceSBarry Smith . snes - the SNES context 37379b94acceSBarry Smith 37389b94acceSBarry Smith Output Parameter: 37397bf4e008SBarry Smith + r - the function (or PETSC_NULL) 374070e92668SMatthew Knepley . func - the function (or PETSC_NULL) 374170e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 37429b94acceSBarry Smith 374336851e7fSLois Curfman McInnes Level: advanced 374436851e7fSLois Curfman McInnes 3745a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 37469b94acceSBarry Smith 37474b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 37489b94acceSBarry Smith @*/ 37497087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 37509b94acceSBarry Smith { 3751a63bb30eSJed Brown PetscErrorCode ierr; 37526cab3a1bSJed Brown DM dm; 3753a63bb30eSJed Brown 37543a40ed3dSBarry Smith PetscFunctionBegin; 37550700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3756a63bb30eSJed Brown if (r) { 3757a63bb30eSJed Brown if (!snes->vec_func) { 3758a63bb30eSJed Brown if (snes->vec_rhs) { 3759a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 3760a63bb30eSJed Brown } else if (snes->vec_sol) { 3761a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 3762a63bb30eSJed Brown } else if (snes->dm) { 3763a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 3764a63bb30eSJed Brown } 3765a63bb30eSJed Brown } 3766a63bb30eSJed Brown *r = snes->vec_func; 3767a63bb30eSJed Brown } 37686cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 37696cab3a1bSJed Brown ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr); 37703a40ed3dSBarry Smith PetscFunctionReturn(0); 37719b94acceSBarry Smith } 37729b94acceSBarry Smith 3773c79ef259SPeter Brune /*@C 3774c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3775c79ef259SPeter Brune 3776c79ef259SPeter Brune Input Parameter: 3777c79ef259SPeter Brune . snes - the SNES context 3778c79ef259SPeter Brune 3779c79ef259SPeter Brune Output Parameter: 3780c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3781c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3782c79ef259SPeter Brune 3783c79ef259SPeter Brune Level: advanced 3784c79ef259SPeter Brune 3785c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3786c79ef259SPeter Brune 3787c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3788c79ef259SPeter Brune @*/ 3789c79ef259SPeter Brune 37904a2ae208SSatish Balay #undef __FUNCT__ 3791646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3792646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3793646217ecSPeter Brune { 37946cab3a1bSJed Brown PetscErrorCode ierr; 37956cab3a1bSJed Brown DM dm; 37966cab3a1bSJed Brown 3797646217ecSPeter Brune PetscFunctionBegin; 3798646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37996cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 38006cab3a1bSJed Brown ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr); 3801646217ecSPeter Brune PetscFunctionReturn(0); 3802646217ecSPeter Brune } 3803646217ecSPeter Brune 38044a2ae208SSatish Balay #undef __FUNCT__ 38054a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 38063c7409f5SSatish Balay /*@C 38073c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3808d850072dSLois Curfman McInnes SNES options in the database. 38093c7409f5SSatish Balay 38103f9fe445SBarry Smith Logically Collective on SNES 3811fee21e36SBarry Smith 3812c7afd0dbSLois Curfman McInnes Input Parameter: 3813c7afd0dbSLois Curfman McInnes + snes - the SNES context 3814c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3815c7afd0dbSLois Curfman McInnes 3816d850072dSLois Curfman McInnes Notes: 3817a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3818c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3819d850072dSLois Curfman McInnes 382036851e7fSLois Curfman McInnes Level: advanced 382136851e7fSLois Curfman McInnes 38223c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3823a86d99e1SLois Curfman McInnes 3824a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 38253c7409f5SSatish Balay @*/ 38267087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 38273c7409f5SSatish Balay { 3828dfbe8321SBarry Smith PetscErrorCode ierr; 38293c7409f5SSatish Balay 38303a40ed3dSBarry Smith PetscFunctionBegin; 38310700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3832639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 38331cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 383494b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 38353a40ed3dSBarry Smith PetscFunctionReturn(0); 38363c7409f5SSatish Balay } 38373c7409f5SSatish Balay 38384a2ae208SSatish Balay #undef __FUNCT__ 38394a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 38403c7409f5SSatish Balay /*@C 3841f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3842d850072dSLois Curfman McInnes SNES options in the database. 38433c7409f5SSatish Balay 38443f9fe445SBarry Smith Logically Collective on SNES 3845fee21e36SBarry Smith 3846c7afd0dbSLois Curfman McInnes Input Parameters: 3847c7afd0dbSLois Curfman McInnes + snes - the SNES context 3848c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3849c7afd0dbSLois Curfman McInnes 3850d850072dSLois Curfman McInnes Notes: 3851a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3852c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3853d850072dSLois Curfman McInnes 385436851e7fSLois Curfman McInnes Level: advanced 385536851e7fSLois Curfman McInnes 38563c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3857a86d99e1SLois Curfman McInnes 3858a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 38593c7409f5SSatish Balay @*/ 38607087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 38613c7409f5SSatish Balay { 3862dfbe8321SBarry Smith PetscErrorCode ierr; 38633c7409f5SSatish Balay 38643a40ed3dSBarry Smith PetscFunctionBegin; 38650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3866639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 38671cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 386894b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 38693a40ed3dSBarry Smith PetscFunctionReturn(0); 38703c7409f5SSatish Balay } 38713c7409f5SSatish Balay 38724a2ae208SSatish Balay #undef __FUNCT__ 38734a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 38749ab63eb5SSatish Balay /*@C 38753c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 38763c7409f5SSatish Balay SNES options in the database. 38773c7409f5SSatish Balay 3878c7afd0dbSLois Curfman McInnes Not Collective 3879c7afd0dbSLois Curfman McInnes 38803c7409f5SSatish Balay Input Parameter: 38813c7409f5SSatish Balay . snes - the SNES context 38823c7409f5SSatish Balay 38833c7409f5SSatish Balay Output Parameter: 38843c7409f5SSatish Balay . prefix - pointer to the prefix string used 38853c7409f5SSatish Balay 38864ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 38879ab63eb5SSatish Balay sufficient length to hold the prefix. 38889ab63eb5SSatish Balay 388936851e7fSLois Curfman McInnes Level: advanced 389036851e7fSLois Curfman McInnes 38913c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 3892a86d99e1SLois Curfman McInnes 3893a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 38943c7409f5SSatish Balay @*/ 38957087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 38963c7409f5SSatish Balay { 3897dfbe8321SBarry Smith PetscErrorCode ierr; 38983c7409f5SSatish Balay 38993a40ed3dSBarry Smith PetscFunctionBegin; 39000700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3901639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 39023a40ed3dSBarry Smith PetscFunctionReturn(0); 39033c7409f5SSatish Balay } 39043c7409f5SSatish Balay 3905b2002411SLois Curfman McInnes 39064a2ae208SSatish Balay #undef __FUNCT__ 39074a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 39083cea93caSBarry Smith /*@C 39093cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 39103cea93caSBarry Smith 39117f6c08e0SMatthew Knepley Level: advanced 39123cea93caSBarry Smith @*/ 39137087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3914b2002411SLois Curfman McInnes { 3915e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3916dfbe8321SBarry Smith PetscErrorCode ierr; 3917b2002411SLois Curfman McInnes 3918b2002411SLois Curfman McInnes PetscFunctionBegin; 3919b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3920c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3921b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3922b2002411SLois Curfman McInnes } 3923da9b6338SBarry Smith 3924da9b6338SBarry Smith #undef __FUNCT__ 3925da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 39267087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3927da9b6338SBarry Smith { 3928dfbe8321SBarry Smith PetscErrorCode ierr; 392977431f27SBarry Smith PetscInt N,i,j; 3930da9b6338SBarry Smith Vec u,uh,fh; 3931da9b6338SBarry Smith PetscScalar value; 3932da9b6338SBarry Smith PetscReal norm; 3933da9b6338SBarry Smith 3934da9b6338SBarry Smith PetscFunctionBegin; 3935da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3936da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3937da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3938da9b6338SBarry Smith 3939da9b6338SBarry Smith /* currently only works for sequential */ 3940da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3941da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3942da9b6338SBarry Smith for (i=0; i<N; i++) { 3943da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 394477431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3945da9b6338SBarry Smith for (j=-10; j<11; j++) { 3946ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3947da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 39483ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3949da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 395077431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3951da9b6338SBarry Smith value = -value; 3952da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3953da9b6338SBarry Smith } 3954da9b6338SBarry Smith } 39556bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 39566bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 3957da9b6338SBarry Smith PetscFunctionReturn(0); 3958da9b6338SBarry Smith } 395971f87433Sdalcinl 396071f87433Sdalcinl #undef __FUNCT__ 3961fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 396271f87433Sdalcinl /*@ 3963fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 396471f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 396571f87433Sdalcinl Newton method. 396671f87433Sdalcinl 39673f9fe445SBarry Smith Logically Collective on SNES 396871f87433Sdalcinl 396971f87433Sdalcinl Input Parameters: 397071f87433Sdalcinl + snes - SNES context 397171f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 397271f87433Sdalcinl 397364ba62caSBarry Smith Options Database: 397464ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 397564ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 397664ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 397764ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 397864ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 397964ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 398064ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 398164ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 398264ba62caSBarry Smith 398371f87433Sdalcinl Notes: 398471f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 398571f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 398671f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 398771f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 398871f87433Sdalcinl solver. 398971f87433Sdalcinl 399071f87433Sdalcinl Level: advanced 399171f87433Sdalcinl 399271f87433Sdalcinl Reference: 399371f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 399471f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 399571f87433Sdalcinl 399671f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 399771f87433Sdalcinl 3998fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 399971f87433Sdalcinl @*/ 40007087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 400171f87433Sdalcinl { 400271f87433Sdalcinl PetscFunctionBegin; 40030700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4004acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 400571f87433Sdalcinl snes->ksp_ewconv = flag; 400671f87433Sdalcinl PetscFunctionReturn(0); 400771f87433Sdalcinl } 400871f87433Sdalcinl 400971f87433Sdalcinl #undef __FUNCT__ 4010fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 401171f87433Sdalcinl /*@ 4012fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 401371f87433Sdalcinl for computing relative tolerance for linear solvers within an 401471f87433Sdalcinl inexact Newton method. 401571f87433Sdalcinl 401671f87433Sdalcinl Not Collective 401771f87433Sdalcinl 401871f87433Sdalcinl Input Parameter: 401971f87433Sdalcinl . snes - SNES context 402071f87433Sdalcinl 402171f87433Sdalcinl Output Parameter: 402271f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 402371f87433Sdalcinl 402471f87433Sdalcinl Notes: 402571f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 402671f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 402771f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 402871f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 402971f87433Sdalcinl solver. 403071f87433Sdalcinl 403171f87433Sdalcinl Level: advanced 403271f87433Sdalcinl 403371f87433Sdalcinl Reference: 403471f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 403571f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 403671f87433Sdalcinl 403771f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 403871f87433Sdalcinl 4039fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 404071f87433Sdalcinl @*/ 40417087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 404271f87433Sdalcinl { 404371f87433Sdalcinl PetscFunctionBegin; 40440700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 404571f87433Sdalcinl PetscValidPointer(flag,2); 404671f87433Sdalcinl *flag = snes->ksp_ewconv; 404771f87433Sdalcinl PetscFunctionReturn(0); 404871f87433Sdalcinl } 404971f87433Sdalcinl 405071f87433Sdalcinl #undef __FUNCT__ 4051fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 405271f87433Sdalcinl /*@ 4053fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 405471f87433Sdalcinl convergence criteria for the linear solvers within an inexact 405571f87433Sdalcinl Newton method. 405671f87433Sdalcinl 40573f9fe445SBarry Smith Logically Collective on SNES 405871f87433Sdalcinl 405971f87433Sdalcinl Input Parameters: 406071f87433Sdalcinl + snes - SNES context 406171f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 406271f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 406371f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 406471f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 406571f87433Sdalcinl (0 <= gamma2 <= 1) 406671f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 406771f87433Sdalcinl . alpha2 - power for safeguard 406871f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 406971f87433Sdalcinl 407071f87433Sdalcinl Note: 407171f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 407271f87433Sdalcinl 407371f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 407471f87433Sdalcinl 407571f87433Sdalcinl Level: advanced 407671f87433Sdalcinl 407771f87433Sdalcinl Reference: 407871f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 407971f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 408071f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 408171f87433Sdalcinl 408271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 408371f87433Sdalcinl 4084fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 408571f87433Sdalcinl @*/ 40867087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 408771f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 408871f87433Sdalcinl { 4089fa9f3622SBarry Smith SNESKSPEW *kctx; 409071f87433Sdalcinl PetscFunctionBegin; 40910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4092fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4093e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 4094c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 4095c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 4096c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 4097c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 4098c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 4099c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 4100c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 410171f87433Sdalcinl 410271f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 410371f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 410471f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 410571f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 410671f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 410771f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 410871f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 410971f87433Sdalcinl 411071f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 4111e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 411271f87433Sdalcinl } 411371f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 4114e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 411571f87433Sdalcinl } 411671f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 4117e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 411871f87433Sdalcinl } 411971f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 4120e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 412171f87433Sdalcinl } 412271f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 4123e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 412471f87433Sdalcinl } 412571f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 4126e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 412771f87433Sdalcinl } 412871f87433Sdalcinl PetscFunctionReturn(0); 412971f87433Sdalcinl } 413071f87433Sdalcinl 413171f87433Sdalcinl #undef __FUNCT__ 4132fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 413371f87433Sdalcinl /*@ 4134fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 413571f87433Sdalcinl convergence criteria for the linear solvers within an inexact 413671f87433Sdalcinl Newton method. 413771f87433Sdalcinl 413871f87433Sdalcinl Not Collective 413971f87433Sdalcinl 414071f87433Sdalcinl Input Parameters: 414171f87433Sdalcinl snes - SNES context 414271f87433Sdalcinl 414371f87433Sdalcinl Output Parameters: 414471f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 414571f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 414671f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 414771f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 414871f87433Sdalcinl (0 <= gamma2 <= 1) 414971f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 415071f87433Sdalcinl . alpha2 - power for safeguard 415171f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 415271f87433Sdalcinl 415371f87433Sdalcinl Level: advanced 415471f87433Sdalcinl 415571f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 415671f87433Sdalcinl 4157fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 415871f87433Sdalcinl @*/ 41597087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 416071f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 416171f87433Sdalcinl { 4162fa9f3622SBarry Smith SNESKSPEW *kctx; 416371f87433Sdalcinl PetscFunctionBegin; 41640700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4165fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4166e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 416771f87433Sdalcinl if(version) *version = kctx->version; 416871f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 416971f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 417071f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 417171f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 417271f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 417371f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 417471f87433Sdalcinl PetscFunctionReturn(0); 417571f87433Sdalcinl } 417671f87433Sdalcinl 417771f87433Sdalcinl #undef __FUNCT__ 4178fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 4179fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 418071f87433Sdalcinl { 418171f87433Sdalcinl PetscErrorCode ierr; 4182fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 418371f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 418471f87433Sdalcinl 418571f87433Sdalcinl PetscFunctionBegin; 4186e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 418771f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 418871f87433Sdalcinl rtol = kctx->rtol_0; 418971f87433Sdalcinl } else { 419071f87433Sdalcinl if (kctx->version == 1) { 419171f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 419271f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 419371f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 419471f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 419571f87433Sdalcinl } else if (kctx->version == 2) { 419671f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 419771f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 419871f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 419971f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 420071f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 420171f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 420271f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 420371f87433Sdalcinl stol = PetscMax(rtol,stol); 420471f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 420571f87433Sdalcinl /* safeguard: avoid oversolving */ 420671f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 420771f87433Sdalcinl stol = PetscMax(rtol,stol); 420871f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 4209e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 421071f87433Sdalcinl } 421171f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 421271f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 421371f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 421471f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 421571f87433Sdalcinl PetscFunctionReturn(0); 421671f87433Sdalcinl } 421771f87433Sdalcinl 421871f87433Sdalcinl #undef __FUNCT__ 4219fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 4220fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 422171f87433Sdalcinl { 422271f87433Sdalcinl PetscErrorCode ierr; 4223fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 422471f87433Sdalcinl PCSide pcside; 422571f87433Sdalcinl Vec lres; 422671f87433Sdalcinl 422771f87433Sdalcinl PetscFunctionBegin; 4228e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 422971f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 423071f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 423171f87433Sdalcinl if (kctx->version == 1) { 4232b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 423371f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 423471f87433Sdalcinl /* KSP residual is true linear residual */ 423571f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 423671f87433Sdalcinl } else { 423771f87433Sdalcinl /* KSP residual is preconditioned residual */ 423871f87433Sdalcinl /* compute true linear residual norm */ 423971f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 424071f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 424171f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 424271f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 42436bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 424471f87433Sdalcinl } 424571f87433Sdalcinl } 424671f87433Sdalcinl PetscFunctionReturn(0); 424771f87433Sdalcinl } 424871f87433Sdalcinl 424971f87433Sdalcinl #undef __FUNCT__ 425071f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 425171f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 425271f87433Sdalcinl { 425371f87433Sdalcinl PetscErrorCode ierr; 425471f87433Sdalcinl 425571f87433Sdalcinl PetscFunctionBegin; 4256fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 425771f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 4258fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 425971f87433Sdalcinl PetscFunctionReturn(0); 426071f87433Sdalcinl } 42616c699258SBarry Smith 42626c699258SBarry Smith #undef __FUNCT__ 42636c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 42646c699258SBarry Smith /*@ 42656c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 42666c699258SBarry Smith 42673f9fe445SBarry Smith Logically Collective on SNES 42686c699258SBarry Smith 42696c699258SBarry Smith Input Parameters: 42706c699258SBarry Smith + snes - the preconditioner context 42716c699258SBarry Smith - dm - the dm 42726c699258SBarry Smith 42736c699258SBarry Smith Level: intermediate 42746c699258SBarry Smith 42756c699258SBarry Smith 42766c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 42776c699258SBarry Smith @*/ 42787087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 42796c699258SBarry Smith { 42806c699258SBarry Smith PetscErrorCode ierr; 4281345fed2cSBarry Smith KSP ksp; 42826cab3a1bSJed Brown SNESDM sdm; 42836c699258SBarry Smith 42846c699258SBarry Smith PetscFunctionBegin; 42850700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4286d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 42876cab3a1bSJed Brown if (snes->dm) { /* Move the SNESDM context over to the new DM unless the new DM already has one */ 42886cab3a1bSJed Brown PetscContainer oldcontainer,container; 42896cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 42906cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr); 42916cab3a1bSJed Brown if (oldcontainer && !container) { 42926cab3a1bSJed Brown ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr); 42936cab3a1bSJed Brown ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr); 42946cab3a1bSJed Brown if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */ 42956cab3a1bSJed Brown sdm->originaldm = dm; 42966cab3a1bSJed Brown } 42976cab3a1bSJed Brown } 42986bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 42996cab3a1bSJed Brown } 43006c699258SBarry Smith snes->dm = dm; 4301345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4302345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4303f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 43042c155ee1SBarry Smith if (snes->pc) { 43052c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 43062c155ee1SBarry Smith } 43076c699258SBarry Smith PetscFunctionReturn(0); 43086c699258SBarry Smith } 43096c699258SBarry Smith 43106c699258SBarry Smith #undef __FUNCT__ 43116c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 43126c699258SBarry Smith /*@ 43136c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 43146c699258SBarry Smith 43153f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 43166c699258SBarry Smith 43176c699258SBarry Smith Input Parameter: 43186c699258SBarry Smith . snes - the preconditioner context 43196c699258SBarry Smith 43206c699258SBarry Smith Output Parameter: 43216c699258SBarry Smith . dm - the dm 43226c699258SBarry Smith 43236c699258SBarry Smith Level: intermediate 43246c699258SBarry Smith 43256c699258SBarry Smith 43266c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 43276c699258SBarry Smith @*/ 43287087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 43296c699258SBarry Smith { 43306cab3a1bSJed Brown PetscErrorCode ierr; 43316cab3a1bSJed Brown 43326c699258SBarry Smith PetscFunctionBegin; 43330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 43346cab3a1bSJed Brown if (!snes->dm) { 43356cab3a1bSJed Brown ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr); 43366cab3a1bSJed Brown } 43376c699258SBarry Smith *dm = snes->dm; 43386c699258SBarry Smith PetscFunctionReturn(0); 43396c699258SBarry Smith } 43400807856dSBarry Smith 434131823bd8SMatthew G Knepley #undef __FUNCT__ 434231823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 434331823bd8SMatthew G Knepley /*@ 4344fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 434531823bd8SMatthew G Knepley 434631823bd8SMatthew G Knepley Collective on SNES 434731823bd8SMatthew G Knepley 434831823bd8SMatthew G Knepley Input Parameters: 434931823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 435031823bd8SMatthew G Knepley - pc - the preconditioner object 435131823bd8SMatthew G Knepley 435231823bd8SMatthew G Knepley Notes: 435331823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 435431823bd8SMatthew G Knepley to configure it using the API). 435531823bd8SMatthew G Knepley 435631823bd8SMatthew G Knepley Level: developer 435731823bd8SMatthew G Knepley 435831823bd8SMatthew G Knepley .keywords: SNES, set, precondition 435931823bd8SMatthew G Knepley .seealso: SNESGetPC() 436031823bd8SMatthew G Knepley @*/ 436131823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 436231823bd8SMatthew G Knepley { 436331823bd8SMatthew G Knepley PetscErrorCode ierr; 436431823bd8SMatthew G Knepley 436531823bd8SMatthew G Knepley PetscFunctionBegin; 436631823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 436731823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 436831823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 436931823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4370bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 437131823bd8SMatthew G Knepley snes->pc = pc; 437231823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 437331823bd8SMatthew G Knepley PetscFunctionReturn(0); 437431823bd8SMatthew G Knepley } 437531823bd8SMatthew G Knepley 437631823bd8SMatthew G Knepley #undef __FUNCT__ 437731823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 437831823bd8SMatthew G Knepley /*@ 4379fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 438031823bd8SMatthew G Knepley 438131823bd8SMatthew G Knepley Not Collective 438231823bd8SMatthew G Knepley 438331823bd8SMatthew G Knepley Input Parameter: 438431823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 438531823bd8SMatthew G Knepley 438631823bd8SMatthew G Knepley Output Parameter: 438731823bd8SMatthew G Knepley . pc - preconditioner context 438831823bd8SMatthew G Knepley 438931823bd8SMatthew G Knepley Level: developer 439031823bd8SMatthew G Knepley 439131823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 439231823bd8SMatthew G Knepley .seealso: SNESSetPC() 439331823bd8SMatthew G Knepley @*/ 439431823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 439531823bd8SMatthew G Knepley { 439631823bd8SMatthew G Knepley PetscErrorCode ierr; 4397a64e098fSPeter Brune const char *optionsprefix; 439831823bd8SMatthew G Knepley 439931823bd8SMatthew G Knepley PetscFunctionBegin; 440031823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 440131823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 440231823bd8SMatthew G Knepley if (!snes->pc) { 440331823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm,&snes->pc);CHKERRQ(ierr); 44044a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr); 440531823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes,snes->pc);CHKERRQ(ierr); 4406a64e098fSPeter Brune ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr); 4407a64e098fSPeter Brune ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr); 4408a64e098fSPeter Brune ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr); 440931823bd8SMatthew G Knepley } 441031823bd8SMatthew G Knepley *pc = snes->pc; 441131823bd8SMatthew G Knepley PetscFunctionReturn(0); 441231823bd8SMatthew G Knepley } 441331823bd8SMatthew G Knepley 44149e764e56SPeter Brune #undef __FUNCT__ 4415f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch" 44169e764e56SPeter Brune /*@ 44178141a3b9SPeter Brune SNESSetSNESLineSearch - Sets the linesearch on the SNES instance. 44189e764e56SPeter Brune 44199e764e56SPeter Brune Collective on SNES 44209e764e56SPeter Brune 44219e764e56SPeter Brune Input Parameters: 44229e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 44239e764e56SPeter Brune - linesearch - the linesearch object 44249e764e56SPeter Brune 44259e764e56SPeter Brune Notes: 4426f1c6b773SPeter Brune Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example, 44279e764e56SPeter Brune to configure it using the API). 44289e764e56SPeter Brune 44299e764e56SPeter Brune Level: developer 44309e764e56SPeter Brune 44319e764e56SPeter Brune .keywords: SNES, set, linesearch 4432f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch() 44339e764e56SPeter Brune @*/ 4434f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch) 44359e764e56SPeter Brune { 44369e764e56SPeter Brune PetscErrorCode ierr; 44379e764e56SPeter Brune 44389e764e56SPeter Brune PetscFunctionBegin; 44399e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4440f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 44419e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 44429e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 4443f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 44449e764e56SPeter Brune snes->linesearch = linesearch; 44459e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 44469e764e56SPeter Brune PetscFunctionReturn(0); 44479e764e56SPeter Brune } 44489e764e56SPeter Brune 44499e764e56SPeter Brune #undef __FUNCT__ 4450f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch" 4451ea5d4fccSPeter Brune /*@C 44528141a3b9SPeter Brune SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 44538141a3b9SPeter Brune or creates a default line search instance associated with the SNES and returns it. 44549e764e56SPeter Brune 44559e764e56SPeter Brune Not Collective 44569e764e56SPeter Brune 44579e764e56SPeter Brune Input Parameter: 44589e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 44599e764e56SPeter Brune 44609e764e56SPeter Brune Output Parameter: 44619e764e56SPeter Brune . linesearch - linesearch context 44629e764e56SPeter Brune 44639e764e56SPeter Brune Level: developer 44649e764e56SPeter Brune 44659e764e56SPeter Brune .keywords: SNES, get, linesearch 4466f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch() 44679e764e56SPeter Brune @*/ 4468f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch) 44699e764e56SPeter Brune { 44709e764e56SPeter Brune PetscErrorCode ierr; 44719e764e56SPeter Brune const char *optionsprefix; 44729e764e56SPeter Brune 44739e764e56SPeter Brune PetscFunctionBegin; 44749e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 44759e764e56SPeter Brune PetscValidPointer(linesearch, 2); 44769e764e56SPeter Brune if (!snes->linesearch) { 44779e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 4478f1c6b773SPeter Brune ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr); 4479f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 4480b1dca40bSPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 44819e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 44829e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 44839e764e56SPeter Brune } 44849e764e56SPeter Brune *linesearch = snes->linesearch; 44859e764e56SPeter Brune PetscFunctionReturn(0); 44869e764e56SPeter Brune } 44879e764e56SPeter Brune 448869b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4489c6db04a5SJed Brown #include <mex.h> 449069b4f73cSBarry Smith 44918f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 44928f6e6473SBarry Smith 44930807856dSBarry Smith #undef __FUNCT__ 44940807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 44950807856dSBarry Smith /* 44960807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 44970807856dSBarry Smith SNESSetFunctionMatlab(). 44980807856dSBarry Smith 44990807856dSBarry Smith Collective on SNES 45000807856dSBarry Smith 45010807856dSBarry Smith Input Parameters: 45020807856dSBarry Smith + snes - the SNES context 45030807856dSBarry Smith - x - input vector 45040807856dSBarry Smith 45050807856dSBarry Smith Output Parameter: 45060807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 45070807856dSBarry Smith 45080807856dSBarry Smith Notes: 45090807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 45100807856dSBarry Smith implementations, so most users would not generally call this routine 45110807856dSBarry Smith themselves. 45120807856dSBarry Smith 45130807856dSBarry Smith Level: developer 45140807856dSBarry Smith 45150807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 45160807856dSBarry Smith 45170807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 451861b2408cSBarry Smith */ 45197087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 45200807856dSBarry Smith { 4521e650e774SBarry Smith PetscErrorCode ierr; 45228f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 45238f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 45248f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 452591621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 4526e650e774SBarry Smith 45270807856dSBarry Smith PetscFunctionBegin; 45280807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 45290807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 45300807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 45310807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 45320807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 45330807856dSBarry Smith 45340807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 4535e650e774SBarry Smith 453691621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4537e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4538e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 453991621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 454091621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 454191621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 45428f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 45438f6e6473SBarry Smith prhs[4] = sctx->ctx; 4544b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 4545e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4546e650e774SBarry Smith mxDestroyArray(prhs[0]); 4547e650e774SBarry Smith mxDestroyArray(prhs[1]); 4548e650e774SBarry Smith mxDestroyArray(prhs[2]); 45498f6e6473SBarry Smith mxDestroyArray(prhs[3]); 4550e650e774SBarry Smith mxDestroyArray(plhs[0]); 45510807856dSBarry Smith PetscFunctionReturn(0); 45520807856dSBarry Smith } 45530807856dSBarry Smith 45540807856dSBarry Smith 45550807856dSBarry Smith #undef __FUNCT__ 45560807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 455761b2408cSBarry Smith /* 45580807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 45590807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4560e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 45610807856dSBarry Smith 45620807856dSBarry Smith Logically Collective on SNES 45630807856dSBarry Smith 45640807856dSBarry Smith Input Parameters: 45650807856dSBarry Smith + snes - the SNES context 45660807856dSBarry Smith . r - vector to store function value 45670807856dSBarry Smith - func - function evaluation routine 45680807856dSBarry Smith 45690807856dSBarry Smith Calling sequence of func: 457061b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 45710807856dSBarry Smith 45720807856dSBarry Smith 45730807856dSBarry Smith Notes: 45740807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 45750807856dSBarry Smith $ f'(x) x = -f(x), 45760807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 45770807856dSBarry Smith 45780807856dSBarry Smith Level: beginner 45790807856dSBarry Smith 45800807856dSBarry Smith .keywords: SNES, nonlinear, set, function 45810807856dSBarry Smith 45820807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 458361b2408cSBarry Smith */ 45847087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 45850807856dSBarry Smith { 45860807856dSBarry Smith PetscErrorCode ierr; 45878f6e6473SBarry Smith SNESMatlabContext *sctx; 45880807856dSBarry Smith 45890807856dSBarry Smith PetscFunctionBegin; 45908f6e6473SBarry Smith /* currently sctx is memory bleed */ 45918f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 45928f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 45938f6e6473SBarry Smith /* 45948f6e6473SBarry Smith This should work, but it doesn't 45958f6e6473SBarry Smith sctx->ctx = ctx; 45968f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 45978f6e6473SBarry Smith */ 45988f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 45998f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 46000807856dSBarry Smith PetscFunctionReturn(0); 46010807856dSBarry Smith } 460269b4f73cSBarry Smith 460361b2408cSBarry Smith #undef __FUNCT__ 460461b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 460561b2408cSBarry Smith /* 460661b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 460761b2408cSBarry Smith SNESSetJacobianMatlab(). 460861b2408cSBarry Smith 460961b2408cSBarry Smith Collective on SNES 461061b2408cSBarry Smith 461161b2408cSBarry Smith Input Parameters: 461261b2408cSBarry Smith + snes - the SNES context 461361b2408cSBarry Smith . x - input vector 461461b2408cSBarry Smith . A, B - the matrices 461561b2408cSBarry Smith - ctx - user context 461661b2408cSBarry Smith 461761b2408cSBarry Smith Output Parameter: 461861b2408cSBarry Smith . flag - structure of the matrix 461961b2408cSBarry Smith 462061b2408cSBarry Smith Level: developer 462161b2408cSBarry Smith 462261b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 462361b2408cSBarry Smith 462461b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 462561b2408cSBarry Smith @*/ 46267087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 462761b2408cSBarry Smith { 462861b2408cSBarry Smith PetscErrorCode ierr; 462961b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 463061b2408cSBarry Smith int nlhs = 2,nrhs = 6; 463161b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 463261b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 463361b2408cSBarry Smith 463461b2408cSBarry Smith PetscFunctionBegin; 463561b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 463661b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 463761b2408cSBarry Smith 463861b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 463961b2408cSBarry Smith 464061b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 464161b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 464261b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 464361b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 464461b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 464561b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 464661b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 464761b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 464861b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 464961b2408cSBarry Smith prhs[5] = sctx->ctx; 4650b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 465161b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 465261b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 465361b2408cSBarry Smith mxDestroyArray(prhs[0]); 465461b2408cSBarry Smith mxDestroyArray(prhs[1]); 465561b2408cSBarry Smith mxDestroyArray(prhs[2]); 465661b2408cSBarry Smith mxDestroyArray(prhs[3]); 465761b2408cSBarry Smith mxDestroyArray(prhs[4]); 465861b2408cSBarry Smith mxDestroyArray(plhs[0]); 465961b2408cSBarry Smith mxDestroyArray(plhs[1]); 466061b2408cSBarry Smith PetscFunctionReturn(0); 466161b2408cSBarry Smith } 466261b2408cSBarry Smith 466361b2408cSBarry Smith 466461b2408cSBarry Smith #undef __FUNCT__ 466561b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 466661b2408cSBarry Smith /* 466761b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 466861b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4669e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 467061b2408cSBarry Smith 467161b2408cSBarry Smith Logically Collective on SNES 467261b2408cSBarry Smith 467361b2408cSBarry Smith Input Parameters: 467461b2408cSBarry Smith + snes - the SNES context 467561b2408cSBarry Smith . A,B - Jacobian matrices 467661b2408cSBarry Smith . func - function evaluation routine 467761b2408cSBarry Smith - ctx - user context 467861b2408cSBarry Smith 467961b2408cSBarry Smith Calling sequence of func: 468061b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 468161b2408cSBarry Smith 468261b2408cSBarry Smith 468361b2408cSBarry Smith Level: developer 468461b2408cSBarry Smith 468561b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 468661b2408cSBarry Smith 468761b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 468861b2408cSBarry Smith */ 46897087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 469061b2408cSBarry Smith { 469161b2408cSBarry Smith PetscErrorCode ierr; 469261b2408cSBarry Smith SNESMatlabContext *sctx; 469361b2408cSBarry Smith 469461b2408cSBarry Smith PetscFunctionBegin; 469561b2408cSBarry Smith /* currently sctx is memory bleed */ 469661b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 469761b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 469861b2408cSBarry Smith /* 469961b2408cSBarry Smith This should work, but it doesn't 470061b2408cSBarry Smith sctx->ctx = ctx; 470161b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 470261b2408cSBarry Smith */ 470361b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 470461b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 470561b2408cSBarry Smith PetscFunctionReturn(0); 470661b2408cSBarry Smith } 470769b4f73cSBarry Smith 4708f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4709f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4710f9eb7ae2SShri Abhyankar /* 4711f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4712f9eb7ae2SShri Abhyankar 4713f9eb7ae2SShri Abhyankar Collective on SNES 4714f9eb7ae2SShri Abhyankar 4715f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4716f9eb7ae2SShri Abhyankar @*/ 47177087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4718f9eb7ae2SShri Abhyankar { 4719f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 472048f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4721f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4722f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4723f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4724f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4725f9eb7ae2SShri Abhyankar 4726f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4727f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4728f9eb7ae2SShri Abhyankar 4729f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4730f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4731f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4732f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4733f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4734f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4735f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4736f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4737f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4738f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4739f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4740f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4741f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4742f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4743f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4744f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4745f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4746f9eb7ae2SShri Abhyankar } 4747f9eb7ae2SShri Abhyankar 4748f9eb7ae2SShri Abhyankar 4749f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4750f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4751f9eb7ae2SShri Abhyankar /* 4752e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4753f9eb7ae2SShri Abhyankar 4754f9eb7ae2SShri Abhyankar Level: developer 4755f9eb7ae2SShri Abhyankar 4756f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4757f9eb7ae2SShri Abhyankar 4758f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4759f9eb7ae2SShri Abhyankar */ 47607087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4761f9eb7ae2SShri Abhyankar { 4762f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4763f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4764f9eb7ae2SShri Abhyankar 4765f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4766f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4767f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4768f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4769f9eb7ae2SShri Abhyankar /* 4770f9eb7ae2SShri Abhyankar This should work, but it doesn't 4771f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4772f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4773f9eb7ae2SShri Abhyankar */ 4774f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4775f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4776f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4777f9eb7ae2SShri Abhyankar } 4778f9eb7ae2SShri Abhyankar 477969b4f73cSBarry Smith #endif 4780