19b94acceSBarry Smith 2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h> /*I "petscsnes.h" I*/ 36cab3a1bSJed Brown #include <petscdmshell.h> /*I "petscdmshell.h" I*/ 4*a64e098fSPeter 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; 3996cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 4006cab3a1bSJed Brown if (snes->mf_operator) { 4016cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4026cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4036cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4046cab3a1bSJed Brown } else { 4056cab3a1bSJed Brown J = B; 4066cab3a1bSJed Brown ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr); 4076cab3a1bSJed Brown } 4086cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr); 4096cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 4106cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 4116cab3a1bSJed Brown } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) { 4126cab3a1bSJed Brown Mat J; 4136cab3a1bSJed Brown void *functx; 4146cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4156cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4166cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4176cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 4186cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr); 4196cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 420caa4e7f2SJed Brown } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 4216cab3a1bSJed Brown Mat J,B; 4226cab3a1bSJed Brown void *functx; 4236cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4246cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4256cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4266cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 4276cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 4286cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,functx);CHKERRQ(ierr); 4296cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 4306cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 431caa4e7f2SJed Brown } else if (!snes->jacobian_pre) { 4326cab3a1bSJed Brown Mat J,B; 4336cab3a1bSJed Brown J = snes->jacobian; 4346cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 4356cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 4366cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 4376cab3a1bSJed Brown } 438caa4e7f2SJed Brown { 43960a3618bSJed Brown PetscBool flg = PETSC_FALSE; 440caa4e7f2SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_kspcompute",&flg,PETSC_NULL);CHKERRQ(ierr); 441caa4e7f2SJed Brown if (flg) { /* Plan to transition to this model */ 442caa4e7f2SJed Brown KSP ksp; 443caa4e7f2SJed Brown ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 444caa4e7f2SJed Brown ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr); 445dfe15315SJed Brown ierr = DMCoarsenHookAdd(snes->dm,PETSC_NULL,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 446caa4e7f2SJed Brown } 447caa4e7f2SJed Brown } 4486cab3a1bSJed Brown PetscFunctionReturn(0); 4496cab3a1bSJed Brown } 4506cab3a1bSJed Brown 4516cab3a1bSJed Brown #undef __FUNCT__ 4524a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions" 4539b94acceSBarry Smith /*@ 45494b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 4559b94acceSBarry Smith 456c7afd0dbSLois Curfman McInnes Collective on SNES 457c7afd0dbSLois Curfman McInnes 4589b94acceSBarry Smith Input Parameter: 4599b94acceSBarry Smith . snes - the SNES context 4609b94acceSBarry Smith 46136851e7fSLois Curfman McInnes Options Database Keys: 462ea630c6eSPeter Brune + -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas 46382738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 46482738288SBarry Smith of the change in the solution between steps 46570441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 466b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 467b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 468b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 4694839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 470ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 471a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 472e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 473b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 4742492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 47582738288SBarry Smith solver; hence iterations will continue until max_it 4761fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 47782738288SBarry Smith of convergence test 478e8105e01SRichard Katz . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 479e8105e01SRichard Katz filename given prints to stdout 480a6570f20SBarry Smith . -snes_monitor_solution - plots solution at each iteration 481a6570f20SBarry Smith . -snes_monitor_residual - plots residual (not its norm) at each iteration 482a6570f20SBarry Smith . -snes_monitor_solution_update - plots update to solution at each iteration 483a6570f20SBarry Smith . -snes_monitor_draw - plots residual norm at each iteration 484e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 4855968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 486fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 48782738288SBarry Smith 48882738288SBarry Smith Options Database for Eisenstat-Walker method: 489fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 4904b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 49136851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 49236851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 49336851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 49436851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 49536851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 49636851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 49782738288SBarry Smith 49811ca99fdSLois Curfman McInnes Notes: 49911ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 5000598bfebSBarry Smith the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>. 50183e2fdc7SBarry Smith 50236851e7fSLois Curfman McInnes Level: beginner 50336851e7fSLois Curfman McInnes 5049b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 5059b94acceSBarry Smith 50669ed319cSSatish Balay .seealso: SNESSetOptionsPrefix() 5079b94acceSBarry Smith @*/ 5087087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 5099b94acceSBarry Smith { 510872b6db9SPeter Brune PetscBool flg,mf,mf_operator,pcset; 511efd51863SBarry Smith PetscInt i,indx,lag,mf_version,grids; 512aa3661deSLisandro Dalcin MatStructure matflag; 51385385478SLisandro Dalcin const char *deft = SNESLS; 51485385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 51585385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 516e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 517649052a6SBarry Smith PetscViewer monviewer; 51885385478SLisandro Dalcin PetscErrorCode ierr; 519*a64e098fSPeter Brune const char *optionsprefix; 5209b94acceSBarry Smith 5213a40ed3dSBarry Smith PetscFunctionBegin; 5220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 523ca161407SBarry Smith 524186905e3SBarry Smith if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 5253194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 5267adad957SLisandro Dalcin if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; } 527b0a32e0cSBarry Smith ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 528d64ed03dSBarry Smith if (flg) { 529186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 5307adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 531186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 532d64ed03dSBarry Smith } 53390d69ab7SBarry Smith /* not used here, but called so will go into help messaage */ 534909c8a9fSBarry Smith ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 53593c39befSBarry Smith 536c60f73f4SPeter Brune ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr); 53757034d6fSHong Zhang ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 538186905e3SBarry Smith 53957034d6fSHong Zhang ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 540b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 541b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 54224254dc1SJed Brown ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 543ddf469c8SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr); 544acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr); 54585385478SLisandro Dalcin 546a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 547a8054027SBarry Smith if (flg) { 548a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 549a8054027SBarry Smith } 550e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 551e35cf81dSBarry Smith if (flg) { 552e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 553e35cf81dSBarry Smith } 554efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 555efd51863SBarry Smith if (flg) { 556efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 557efd51863SBarry Smith } 558a8054027SBarry Smith 55985385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 56085385478SLisandro Dalcin if (flg) { 56185385478SLisandro Dalcin switch (indx) { 5627f7931b9SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 5637f7931b9SBarry Smith case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 56485385478SLisandro Dalcin } 56585385478SLisandro Dalcin } 56685385478SLisandro Dalcin 567acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr); 568186905e3SBarry Smith 569fdacfa88SPeter Brune ierr = PetscOptionsEList("-snes_norm_type","SNES Norm type","SNESSetNormType",SNESNormTypes,5,"function",&indx,&flg);CHKERRQ(ierr); 570fdacfa88SPeter Brune if (flg) { ierr = SNESSetNormType(snes,(SNESNormType)indx);CHKERRQ(ierr); } 571fdacfa88SPeter Brune 57285385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 57385385478SLisandro Dalcin 574acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 575186905e3SBarry Smith 576fa9f3622SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 577fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 578fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 579fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 580fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 581fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 582fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 583186905e3SBarry Smith 58490d69ab7SBarry Smith flg = PETSC_FALSE; 585acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 586a6570f20SBarry Smith if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 587eabae89aSBarry Smith 588a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 589e8105e01SRichard Katz if (flg) { 590649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 591649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 592e8105e01SRichard Katz } 593eabae89aSBarry Smith 594b271bb04SBarry Smith ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 595b271bb04SBarry Smith if (flg) { 596b271bb04SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 597b271bb04SBarry Smith } 598b271bb04SBarry Smith 599a6570f20SBarry Smith ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 600eabae89aSBarry Smith if (flg) { 601649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 602f1bef1bcSMatthew Knepley ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 603e8105e01SRichard Katz } 604eabae89aSBarry Smith 605a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 606eabae89aSBarry Smith if (flg) { 607649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 608649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 609eabae89aSBarry Smith } 610eabae89aSBarry Smith 6115180491cSLisandro Dalcin ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 6125180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 6135180491cSLisandro Dalcin 61490d69ab7SBarry Smith flg = PETSC_FALSE; 615acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 616a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 61790d69ab7SBarry Smith flg = PETSC_FALSE; 618acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 619a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 62090d69ab7SBarry Smith flg = PETSC_FALSE; 621acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 622a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 62390d69ab7SBarry Smith flg = PETSC_FALSE; 624acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 625a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 62690d69ab7SBarry Smith flg = PETSC_FALSE; 627acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 628b271bb04SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 629e24b481bSBarry Smith 63090d69ab7SBarry Smith flg = PETSC_FALSE; 631acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 6324b27c08aSLois Curfman McInnes if (flg) { 6336cab3a1bSJed Brown void *functx; 6346cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 6356cab3a1bSJed Brown ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr); 636ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 6379b94acceSBarry Smith } 638639f9d9dSBarry Smith 639aa3661deSLisandro Dalcin mf = mf_operator = PETSC_FALSE; 640aa3661deSLisandro Dalcin flg = PETSC_FALSE; 641acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr); 642a8248277SBarry Smith if (flg && mf_operator) { 643a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 644a8248277SBarry Smith mf = PETSC_TRUE; 645a8248277SBarry Smith } 646aa3661deSLisandro Dalcin flg = PETSC_FALSE; 647acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr); 648aa3661deSLisandro Dalcin if (!flg && mf_operator) mf = PETSC_TRUE; 649aa3661deSLisandro Dalcin mf_version = 1; 650aa3661deSLisandro Dalcin ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr); 651aa3661deSLisandro Dalcin 652d28543b3SPeter Brune 65389b92e6fSPeter Brune /* GS Options */ 65489b92e6fSPeter Brune ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr); 65589b92e6fSPeter Brune 65676b2cf59SMatthew Knepley for(i = 0; i < numberofsetfromoptions; i++) { 65776b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 65876b2cf59SMatthew Knepley } 65976b2cf59SMatthew Knepley 660e7788613SBarry Smith if (snes->ops->setfromoptions) { 661e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 662639f9d9dSBarry Smith } 6635d973c19SBarry Smith 6645d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 6655d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 666b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 6674bbc92c1SBarry Smith 668aa3661deSLisandro Dalcin if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 6691cee3971SBarry Smith 6701cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 671aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 672aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 67385385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 67493993e2dSLois Curfman McInnes 6759e764e56SPeter Brune if (!snes->linesearch) { 676f1c6b773SPeter Brune ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 6779e764e56SPeter Brune } 678f1c6b773SPeter Brune ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr); 6799e764e56SPeter Brune 68051e86f29SPeter Brune /* if someone has set the SNES PC type, create it. */ 68151e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 68251e86f29SPeter Brune ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 68351e86f29SPeter Brune if (pcset && (!snes->pc)) { 68451e86f29SPeter Brune ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr); 68551e86f29SPeter Brune } 6863a40ed3dSBarry Smith PetscFunctionReturn(0); 6879b94acceSBarry Smith } 6889b94acceSBarry Smith 689d25893d9SBarry Smith #undef __FUNCT__ 690d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 691d25893d9SBarry Smith /*@ 692d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 693d25893d9SBarry Smith the nonlinear solvers. 694d25893d9SBarry Smith 695d25893d9SBarry Smith Logically Collective on SNES 696d25893d9SBarry Smith 697d25893d9SBarry Smith Input Parameters: 698d25893d9SBarry Smith + snes - the SNES context 699d25893d9SBarry Smith . compute - function to compute the context 700d25893d9SBarry Smith - destroy - function to destroy the context 701d25893d9SBarry Smith 702d25893d9SBarry Smith Level: intermediate 703d25893d9SBarry Smith 704d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 705d25893d9SBarry Smith 706d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 707d25893d9SBarry Smith @*/ 708d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 709d25893d9SBarry Smith { 710d25893d9SBarry Smith PetscFunctionBegin; 711d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 712d25893d9SBarry Smith snes->ops->usercompute = compute; 713d25893d9SBarry Smith snes->ops->userdestroy = destroy; 714d25893d9SBarry Smith PetscFunctionReturn(0); 715d25893d9SBarry Smith } 716a847f771SSatish Balay 7174a2ae208SSatish Balay #undef __FUNCT__ 7184a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 719b07ff414SBarry Smith /*@ 7209b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 7219b94acceSBarry Smith the nonlinear solvers. 7229b94acceSBarry Smith 7233f9fe445SBarry Smith Logically Collective on SNES 724fee21e36SBarry Smith 725c7afd0dbSLois Curfman McInnes Input Parameters: 726c7afd0dbSLois Curfman McInnes + snes - the SNES context 727c7afd0dbSLois Curfman McInnes - usrP - optional user context 728c7afd0dbSLois Curfman McInnes 72936851e7fSLois Curfman McInnes Level: intermediate 73036851e7fSLois Curfman McInnes 7319b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 7329b94acceSBarry Smith 733ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext() 7349b94acceSBarry Smith @*/ 7357087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 7369b94acceSBarry Smith { 7371b2093e4SBarry Smith PetscErrorCode ierr; 738b07ff414SBarry Smith KSP ksp; 7391b2093e4SBarry Smith 7403a40ed3dSBarry Smith PetscFunctionBegin; 7410700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 742b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 743b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 7449b94acceSBarry Smith snes->user = usrP; 7453a40ed3dSBarry Smith PetscFunctionReturn(0); 7469b94acceSBarry Smith } 74774679c65SBarry Smith 7484a2ae208SSatish Balay #undef __FUNCT__ 7494a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 750b07ff414SBarry Smith /*@ 7519b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 7529b94acceSBarry Smith nonlinear solvers. 7539b94acceSBarry Smith 754c7afd0dbSLois Curfman McInnes Not Collective 755c7afd0dbSLois Curfman McInnes 7569b94acceSBarry Smith Input Parameter: 7579b94acceSBarry Smith . snes - SNES context 7589b94acceSBarry Smith 7599b94acceSBarry Smith Output Parameter: 7609b94acceSBarry Smith . usrP - user context 7619b94acceSBarry Smith 76236851e7fSLois Curfman McInnes Level: intermediate 76336851e7fSLois Curfman McInnes 7649b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 7659b94acceSBarry Smith 7669b94acceSBarry Smith .seealso: SNESSetApplicationContext() 7679b94acceSBarry Smith @*/ 768e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 7699b94acceSBarry Smith { 7703a40ed3dSBarry Smith PetscFunctionBegin; 7710700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 772e71120c6SJed Brown *(void**)usrP = snes->user; 7733a40ed3dSBarry Smith PetscFunctionReturn(0); 7749b94acceSBarry Smith } 77574679c65SBarry Smith 7764a2ae208SSatish Balay #undef __FUNCT__ 7774a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 7789b94acceSBarry Smith /*@ 779c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 780c8228a4eSBarry Smith at this time. 7819b94acceSBarry Smith 782c7afd0dbSLois Curfman McInnes Not Collective 783c7afd0dbSLois Curfman McInnes 7849b94acceSBarry Smith Input Parameter: 7859b94acceSBarry Smith . snes - SNES context 7869b94acceSBarry Smith 7879b94acceSBarry Smith Output Parameter: 7889b94acceSBarry Smith . iter - iteration number 7899b94acceSBarry Smith 790c8228a4eSBarry Smith Notes: 791c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 792c8228a4eSBarry Smith 793c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 79408405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 79508405cd6SLois Curfman McInnes .vb 79608405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 79708405cd6SLois Curfman McInnes if (!(it % 2)) { 79808405cd6SLois Curfman McInnes [compute Jacobian here] 79908405cd6SLois Curfman McInnes } 80008405cd6SLois Curfman McInnes .ve 801c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 80208405cd6SLois Curfman McInnes recomputed every second SNES iteration. 803c8228a4eSBarry Smith 80436851e7fSLois Curfman McInnes Level: intermediate 80536851e7fSLois Curfman McInnes 8062b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 8072b668275SBarry Smith 808b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 8099b94acceSBarry Smith @*/ 8107087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 8119b94acceSBarry Smith { 8123a40ed3dSBarry Smith PetscFunctionBegin; 8130700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8144482741eSBarry Smith PetscValidIntPointer(iter,2); 8159b94acceSBarry Smith *iter = snes->iter; 8163a40ed3dSBarry Smith PetscFunctionReturn(0); 8179b94acceSBarry Smith } 81874679c65SBarry Smith 8194a2ae208SSatish Balay #undef __FUNCT__ 820360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber" 821360c497dSPeter Brune /*@ 822360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 823360c497dSPeter Brune 824360c497dSPeter Brune Not Collective 825360c497dSPeter Brune 826360c497dSPeter Brune Input Parameter: 827360c497dSPeter Brune . snes - SNES context 828360c497dSPeter Brune . iter - iteration number 829360c497dSPeter Brune 830360c497dSPeter Brune Level: developer 831360c497dSPeter Brune 832360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number, 833360c497dSPeter Brune 834360c497dSPeter Brune .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 835360c497dSPeter Brune @*/ 836360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 837360c497dSPeter Brune { 838360c497dSPeter Brune PetscErrorCode ierr; 839360c497dSPeter Brune 840360c497dSPeter Brune PetscFunctionBegin; 841360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 842360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 843360c497dSPeter Brune snes->iter = iter; 844360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 845360c497dSPeter Brune PetscFunctionReturn(0); 846360c497dSPeter Brune } 847360c497dSPeter Brune 848360c497dSPeter Brune #undef __FUNCT__ 8494a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 8509b94acceSBarry Smith /*@ 8519b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 8529b94acceSBarry Smith with SNESSSetFunction(). 8539b94acceSBarry Smith 854c7afd0dbSLois Curfman McInnes Collective on SNES 855c7afd0dbSLois Curfman McInnes 8569b94acceSBarry Smith Input Parameter: 8579b94acceSBarry Smith . snes - SNES context 8589b94acceSBarry Smith 8599b94acceSBarry Smith Output Parameter: 8609b94acceSBarry Smith . fnorm - 2-norm of function 8619b94acceSBarry Smith 86236851e7fSLois Curfman McInnes Level: intermediate 86336851e7fSLois Curfman McInnes 8649b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 865a86d99e1SLois Curfman McInnes 866b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 8679b94acceSBarry Smith @*/ 8687087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 8699b94acceSBarry Smith { 8703a40ed3dSBarry Smith PetscFunctionBegin; 8710700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8724482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 8739b94acceSBarry Smith *fnorm = snes->norm; 8743a40ed3dSBarry Smith PetscFunctionReturn(0); 8759b94acceSBarry Smith } 87674679c65SBarry Smith 877360c497dSPeter Brune 878360c497dSPeter Brune #undef __FUNCT__ 879360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm" 880360c497dSPeter Brune /*@ 881360c497dSPeter Brune SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm(). 882360c497dSPeter Brune 883360c497dSPeter Brune Collective on SNES 884360c497dSPeter Brune 885360c497dSPeter Brune Input Parameter: 886360c497dSPeter Brune . snes - SNES context 887360c497dSPeter Brune . fnorm - 2-norm of function 888360c497dSPeter Brune 889360c497dSPeter Brune Level: developer 890360c497dSPeter Brune 891360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm 892360c497dSPeter Brune 893360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm(). 894360c497dSPeter Brune @*/ 895360c497dSPeter Brune PetscErrorCode SNESSetFunctionNorm(SNES snes,PetscReal fnorm) 896360c497dSPeter Brune { 897360c497dSPeter Brune 898360c497dSPeter Brune PetscErrorCode ierr; 899360c497dSPeter Brune 900360c497dSPeter Brune PetscFunctionBegin; 901360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 902360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 903360c497dSPeter Brune snes->norm = fnorm; 904360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 905360c497dSPeter Brune PetscFunctionReturn(0); 906360c497dSPeter Brune } 907360c497dSPeter Brune 9084a2ae208SSatish Balay #undef __FUNCT__ 909b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 9109b94acceSBarry Smith /*@ 911b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 9129b94acceSBarry Smith attempted by the nonlinear solver. 9139b94acceSBarry Smith 914c7afd0dbSLois Curfman McInnes Not Collective 915c7afd0dbSLois Curfman McInnes 9169b94acceSBarry Smith Input Parameter: 9179b94acceSBarry Smith . snes - SNES context 9189b94acceSBarry Smith 9199b94acceSBarry Smith Output Parameter: 9209b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 9219b94acceSBarry Smith 922c96a6f78SLois Curfman McInnes Notes: 923c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 924c96a6f78SLois Curfman McInnes 92536851e7fSLois Curfman McInnes Level: intermediate 92636851e7fSLois Curfman McInnes 9279b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 92858ebbce7SBarry Smith 929e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 93058ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 9319b94acceSBarry Smith @*/ 9327087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 9339b94acceSBarry Smith { 9343a40ed3dSBarry Smith PetscFunctionBegin; 9350700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9364482741eSBarry Smith PetscValidIntPointer(nfails,2); 93750ffb88aSMatthew Knepley *nfails = snes->numFailures; 93850ffb88aSMatthew Knepley PetscFunctionReturn(0); 93950ffb88aSMatthew Knepley } 94050ffb88aSMatthew Knepley 94150ffb88aSMatthew Knepley #undef __FUNCT__ 942b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 94350ffb88aSMatthew Knepley /*@ 944b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 94550ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 94650ffb88aSMatthew Knepley 94750ffb88aSMatthew Knepley Not Collective 94850ffb88aSMatthew Knepley 94950ffb88aSMatthew Knepley Input Parameters: 95050ffb88aSMatthew Knepley + snes - SNES context 95150ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 95250ffb88aSMatthew Knepley 95350ffb88aSMatthew Knepley Level: intermediate 95450ffb88aSMatthew Knepley 95550ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 95658ebbce7SBarry Smith 957e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 95858ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 95950ffb88aSMatthew Knepley @*/ 9607087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 96150ffb88aSMatthew Knepley { 96250ffb88aSMatthew Knepley PetscFunctionBegin; 9630700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 96450ffb88aSMatthew Knepley snes->maxFailures = maxFails; 96550ffb88aSMatthew Knepley PetscFunctionReturn(0); 96650ffb88aSMatthew Knepley } 96750ffb88aSMatthew Knepley 96850ffb88aSMatthew Knepley #undef __FUNCT__ 969b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 97050ffb88aSMatthew Knepley /*@ 971b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 97250ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 97350ffb88aSMatthew Knepley 97450ffb88aSMatthew Knepley Not Collective 97550ffb88aSMatthew Knepley 97650ffb88aSMatthew Knepley Input Parameter: 97750ffb88aSMatthew Knepley . snes - SNES context 97850ffb88aSMatthew Knepley 97950ffb88aSMatthew Knepley Output Parameter: 98050ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 98150ffb88aSMatthew Knepley 98250ffb88aSMatthew Knepley Level: intermediate 98350ffb88aSMatthew Knepley 98450ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 98558ebbce7SBarry Smith 986e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 98758ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 98858ebbce7SBarry Smith 98950ffb88aSMatthew Knepley @*/ 9907087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 99150ffb88aSMatthew Knepley { 99250ffb88aSMatthew Knepley PetscFunctionBegin; 9930700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9944482741eSBarry Smith PetscValidIntPointer(maxFails,2); 99550ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 9963a40ed3dSBarry Smith PetscFunctionReturn(0); 9979b94acceSBarry Smith } 998a847f771SSatish Balay 9994a2ae208SSatish Balay #undef __FUNCT__ 10002541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 10012541af92SBarry Smith /*@ 10022541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 10032541af92SBarry Smith done by SNES. 10042541af92SBarry Smith 10052541af92SBarry Smith Not Collective 10062541af92SBarry Smith 10072541af92SBarry Smith Input Parameter: 10082541af92SBarry Smith . snes - SNES context 10092541af92SBarry Smith 10102541af92SBarry Smith Output Parameter: 10112541af92SBarry Smith . nfuncs - number of evaluations 10122541af92SBarry Smith 10132541af92SBarry Smith Level: intermediate 10142541af92SBarry Smith 10152541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 101658ebbce7SBarry Smith 1017e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 10182541af92SBarry Smith @*/ 10197087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 10202541af92SBarry Smith { 10212541af92SBarry Smith PetscFunctionBegin; 10220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10232541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 10242541af92SBarry Smith *nfuncs = snes->nfuncs; 10252541af92SBarry Smith PetscFunctionReturn(0); 10262541af92SBarry Smith } 10272541af92SBarry Smith 10282541af92SBarry Smith #undef __FUNCT__ 10293d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 10303d4c4710SBarry Smith /*@ 10313d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 10323d4c4710SBarry Smith linear solvers. 10333d4c4710SBarry Smith 10343d4c4710SBarry Smith Not Collective 10353d4c4710SBarry Smith 10363d4c4710SBarry Smith Input Parameter: 10373d4c4710SBarry Smith . snes - SNES context 10383d4c4710SBarry Smith 10393d4c4710SBarry Smith Output Parameter: 10403d4c4710SBarry Smith . nfails - number of failed solves 10413d4c4710SBarry Smith 10423d4c4710SBarry Smith Notes: 10433d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 10443d4c4710SBarry Smith 10453d4c4710SBarry Smith Level: intermediate 10463d4c4710SBarry Smith 10473d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 104858ebbce7SBarry Smith 1049e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 10503d4c4710SBarry Smith @*/ 10517087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 10523d4c4710SBarry Smith { 10533d4c4710SBarry Smith PetscFunctionBegin; 10540700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10553d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 10563d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 10573d4c4710SBarry Smith PetscFunctionReturn(0); 10583d4c4710SBarry Smith } 10593d4c4710SBarry Smith 10603d4c4710SBarry Smith #undef __FUNCT__ 10613d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 10623d4c4710SBarry Smith /*@ 10633d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 10643d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 10653d4c4710SBarry Smith 10663f9fe445SBarry Smith Logically Collective on SNES 10673d4c4710SBarry Smith 10683d4c4710SBarry Smith Input Parameters: 10693d4c4710SBarry Smith + snes - SNES context 10703d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 10713d4c4710SBarry Smith 10723d4c4710SBarry Smith Level: intermediate 10733d4c4710SBarry Smith 1074a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 10753d4c4710SBarry Smith 10763d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 10773d4c4710SBarry Smith 107858ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 10793d4c4710SBarry Smith @*/ 10807087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 10813d4c4710SBarry Smith { 10823d4c4710SBarry Smith PetscFunctionBegin; 10830700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1084c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 10853d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 10863d4c4710SBarry Smith PetscFunctionReturn(0); 10873d4c4710SBarry Smith } 10883d4c4710SBarry Smith 10893d4c4710SBarry Smith #undef __FUNCT__ 10903d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 10913d4c4710SBarry Smith /*@ 10923d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 10933d4c4710SBarry Smith are allowed before SNES terminates 10943d4c4710SBarry Smith 10953d4c4710SBarry Smith Not Collective 10963d4c4710SBarry Smith 10973d4c4710SBarry Smith Input Parameter: 10983d4c4710SBarry Smith . snes - SNES context 10993d4c4710SBarry Smith 11003d4c4710SBarry Smith Output Parameter: 11013d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 11023d4c4710SBarry Smith 11033d4c4710SBarry Smith Level: intermediate 11043d4c4710SBarry Smith 11053d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 11063d4c4710SBarry Smith 11073d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 11083d4c4710SBarry Smith 1109e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 11103d4c4710SBarry Smith @*/ 11117087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 11123d4c4710SBarry Smith { 11133d4c4710SBarry Smith PetscFunctionBegin; 11140700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11153d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 11163d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 11173d4c4710SBarry Smith PetscFunctionReturn(0); 11183d4c4710SBarry Smith } 11193d4c4710SBarry Smith 11203d4c4710SBarry Smith #undef __FUNCT__ 1121b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 1122c96a6f78SLois Curfman McInnes /*@ 1123b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1124c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1125c96a6f78SLois Curfman McInnes 1126c7afd0dbSLois Curfman McInnes Not Collective 1127c7afd0dbSLois Curfman McInnes 1128c96a6f78SLois Curfman McInnes Input Parameter: 1129c96a6f78SLois Curfman McInnes . snes - SNES context 1130c96a6f78SLois Curfman McInnes 1131c96a6f78SLois Curfman McInnes Output Parameter: 1132c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1133c96a6f78SLois Curfman McInnes 1134c96a6f78SLois Curfman McInnes Notes: 1135c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1136c96a6f78SLois Curfman McInnes 113736851e7fSLois Curfman McInnes Level: intermediate 113836851e7fSLois Curfman McInnes 1139c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 11402b668275SBarry Smith 11418c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 1142c96a6f78SLois Curfman McInnes @*/ 11437087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 1144c96a6f78SLois Curfman McInnes { 11453a40ed3dSBarry Smith PetscFunctionBegin; 11460700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11474482741eSBarry Smith PetscValidIntPointer(lits,2); 1148c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 11493a40ed3dSBarry Smith PetscFunctionReturn(0); 1150c96a6f78SLois Curfman McInnes } 1151c96a6f78SLois Curfman McInnes 11524a2ae208SSatish Balay #undef __FUNCT__ 115394b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 115452baeb72SSatish Balay /*@ 115594b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 11569b94acceSBarry Smith 115794b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 1158c7afd0dbSLois Curfman McInnes 11599b94acceSBarry Smith Input Parameter: 11609b94acceSBarry Smith . snes - the SNES context 11619b94acceSBarry Smith 11629b94acceSBarry Smith Output Parameter: 116394b7f48cSBarry Smith . ksp - the KSP context 11649b94acceSBarry Smith 11659b94acceSBarry Smith Notes: 116694b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 11679b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 11682999313aSBarry Smith PC contexts as well. 11699b94acceSBarry Smith 117036851e7fSLois Curfman McInnes Level: beginner 117136851e7fSLois Curfman McInnes 117294b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 11739b94acceSBarry Smith 11742999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 11759b94acceSBarry Smith @*/ 11767087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 11779b94acceSBarry Smith { 11781cee3971SBarry Smith PetscErrorCode ierr; 11791cee3971SBarry Smith 11803a40ed3dSBarry Smith PetscFunctionBegin; 11810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11824482741eSBarry Smith PetscValidPointer(ksp,2); 11831cee3971SBarry Smith 11841cee3971SBarry Smith if (!snes->ksp) { 11851cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 11861cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 11871cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 11881cee3971SBarry Smith } 118994b7f48cSBarry Smith *ksp = snes->ksp; 11903a40ed3dSBarry Smith PetscFunctionReturn(0); 11919b94acceSBarry Smith } 119282bf6240SBarry Smith 11934a2ae208SSatish Balay #undef __FUNCT__ 11942999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 11952999313aSBarry Smith /*@ 11962999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 11972999313aSBarry Smith 11982999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 11992999313aSBarry Smith 12002999313aSBarry Smith Input Parameters: 12012999313aSBarry Smith + snes - the SNES context 12022999313aSBarry Smith - ksp - the KSP context 12032999313aSBarry Smith 12042999313aSBarry Smith Notes: 12052999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 12062999313aSBarry Smith so this routine is rarely needed. 12072999313aSBarry Smith 12082999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 12092999313aSBarry Smith decreased by one. 12102999313aSBarry Smith 12112999313aSBarry Smith Level: developer 12122999313aSBarry Smith 12132999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 12142999313aSBarry Smith 12152999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 12162999313aSBarry Smith @*/ 12177087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 12182999313aSBarry Smith { 12192999313aSBarry Smith PetscErrorCode ierr; 12202999313aSBarry Smith 12212999313aSBarry Smith PetscFunctionBegin; 12220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12230700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 12242999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 12257dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1226906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 12272999313aSBarry Smith snes->ksp = ksp; 12282999313aSBarry Smith PetscFunctionReturn(0); 12292999313aSBarry Smith } 12302999313aSBarry Smith 12317adad957SLisandro Dalcin #if 0 12322999313aSBarry Smith #undef __FUNCT__ 12334a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 12346849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1235e24b481bSBarry Smith { 1236e24b481bSBarry Smith PetscFunctionBegin; 1237e24b481bSBarry Smith PetscFunctionReturn(0); 1238e24b481bSBarry Smith } 12397adad957SLisandro Dalcin #endif 1240e24b481bSBarry Smith 12419b94acceSBarry Smith /* -----------------------------------------------------------*/ 12424a2ae208SSatish Balay #undef __FUNCT__ 12434a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 124452baeb72SSatish Balay /*@ 12459b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 12469b94acceSBarry Smith 1247c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1248c7afd0dbSLois Curfman McInnes 1249c7afd0dbSLois Curfman McInnes Input Parameters: 1250906ed7ccSBarry Smith . comm - MPI communicator 12519b94acceSBarry Smith 12529b94acceSBarry Smith Output Parameter: 12539b94acceSBarry Smith . outsnes - the new SNES context 12549b94acceSBarry Smith 1255c7afd0dbSLois Curfman McInnes Options Database Keys: 1256c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1257c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1258c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1259c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1260c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1261c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1262c1f60f51SBarry Smith 126336851e7fSLois Curfman McInnes Level: beginner 126436851e7fSLois Curfman McInnes 12659b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 12669b94acceSBarry Smith 1267a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1268a8054027SBarry Smith 12699b94acceSBarry Smith @*/ 12707087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 12719b94acceSBarry Smith { 1272dfbe8321SBarry Smith PetscErrorCode ierr; 12739b94acceSBarry Smith SNES snes; 1274fa9f3622SBarry Smith SNESKSPEW *kctx; 127537fcc0dbSBarry Smith 12763a40ed3dSBarry Smith PetscFunctionBegin; 1277ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 12788ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 12798ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 12808ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 12818ba1e511SMatthew Knepley #endif 12828ba1e511SMatthew Knepley 12833194b578SJed Brown ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 12847adad957SLisandro Dalcin 128585385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 12862c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 128788976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 12889b94acceSBarry Smith snes->max_its = 50; 12899750a799SBarry Smith snes->max_funcs = 10000; 12909b94acceSBarry Smith snes->norm = 0.0; 1291fdacfa88SPeter Brune snes->normtype = SNES_NORM_FUNCTION; 1292b4874afaSBarry Smith snes->rtol = 1.e-8; 1293b4874afaSBarry Smith snes->ttol = 0.0; 129470441072SBarry Smith snes->abstol = 1.e-50; 1295c60f73f4SPeter Brune snes->stol = 1.e-8; 12964b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 12979b94acceSBarry Smith snes->nfuncs = 0; 129850ffb88aSMatthew Knepley snes->numFailures = 0; 129950ffb88aSMatthew Knepley snes->maxFailures = 1; 13007a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1301e35cf81dSBarry Smith snes->lagjacobian = 1; 1302a8054027SBarry Smith snes->lagpreconditioner = 1; 1303639f9d9dSBarry Smith snes->numbermonitors = 0; 13049b94acceSBarry Smith snes->data = 0; 13054dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1306186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 13076f24a144SLois Curfman McInnes snes->nwork = 0; 130858c9b817SLisandro Dalcin snes->work = 0; 130958c9b817SLisandro Dalcin snes->nvwork = 0; 131058c9b817SLisandro Dalcin snes->vwork = 0; 1311758f92a0SBarry Smith snes->conv_hist_len = 0; 1312758f92a0SBarry Smith snes->conv_hist_max = 0; 1313758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1314758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1315758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1316e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1317e4ed7901SPeter Brune snes->norm_init = 0.; 1318e4ed7901SPeter Brune snes->norm_init_set = PETSC_FALSE; 1319184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 132089b92e6fSPeter Brune snes->gssweeps = 1; 13219b94acceSBarry Smith 13223d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 13233d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 13243d4c4710SBarry Smith 13259b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 132638f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 13279b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 13289b94acceSBarry Smith kctx->version = 2; 13299b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 13309b94acceSBarry Smith this was too large for some test cases */ 133175567043SBarry Smith kctx->rtol_last = 0.0; 13329b94acceSBarry Smith kctx->rtol_max = .9; 13339b94acceSBarry Smith kctx->gamma = 1.0; 133462d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 133571f87433Sdalcinl kctx->alpha2 = kctx->alpha; 13369b94acceSBarry Smith kctx->threshold = .1; 133775567043SBarry Smith kctx->lresid_last = 0.0; 133875567043SBarry Smith kctx->norm_last = 0.0; 13399b94acceSBarry Smith 13409b94acceSBarry Smith *outsnes = snes; 13413a40ed3dSBarry Smith PetscFunctionReturn(0); 13429b94acceSBarry Smith } 13439b94acceSBarry Smith 13444a2ae208SSatish Balay #undef __FUNCT__ 13454a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 13469b94acceSBarry Smith /*@C 13479b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 13489b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 13499b94acceSBarry Smith equations. 13509b94acceSBarry Smith 13513f9fe445SBarry Smith Logically Collective on SNES 1352fee21e36SBarry Smith 1353c7afd0dbSLois Curfman McInnes Input Parameters: 1354c7afd0dbSLois Curfman McInnes + snes - the SNES context 1355c7afd0dbSLois Curfman McInnes . r - vector to store function value 1356de044059SHong Zhang . func - function evaluation routine 1357c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1358c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 13599b94acceSBarry Smith 1360c7afd0dbSLois Curfman McInnes Calling sequence of func: 13618d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1362c7afd0dbSLois Curfman McInnes 1363c586c404SJed Brown + snes - the SNES context 1364c586c404SJed Brown . x - state at which to evaluate residual 1365c586c404SJed Brown . f - vector to put residual 1366c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 13679b94acceSBarry Smith 13689b94acceSBarry Smith Notes: 13699b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 13709b94acceSBarry Smith $ f'(x) x = -f(x), 1371c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 13729b94acceSBarry Smith 137336851e7fSLois Curfman McInnes Level: beginner 137436851e7fSLois Curfman McInnes 13759b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 13769b94acceSBarry Smith 13778b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard() 13789b94acceSBarry Smith @*/ 13797087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 13809b94acceSBarry Smith { 138185385478SLisandro Dalcin PetscErrorCode ierr; 13826cab3a1bSJed Brown DM dm; 13836cab3a1bSJed Brown 13843a40ed3dSBarry Smith PetscFunctionBegin; 13850700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1386d2a683ecSLisandro Dalcin if (r) { 1387d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1388d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 138985385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 13906bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 139185385478SLisandro Dalcin snes->vec_func = r; 1392d2a683ecSLisandro Dalcin } 13936cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 13946cab3a1bSJed Brown ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr); 13953a40ed3dSBarry Smith PetscFunctionReturn(0); 13969b94acceSBarry Smith } 13979b94acceSBarry Smith 1398646217ecSPeter Brune 1399646217ecSPeter Brune #undef __FUNCT__ 1400e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction" 1401e4ed7901SPeter Brune /*@C 1402e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1403e4ed7901SPeter Brune function norm at the initialization of the method. In some 1404e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1405e4ed7901SPeter Brune SNESSolve. This function allows one to avoid a redundant call 1406e4ed7901SPeter Brune to SNESComputeFunction in that case. 1407e4ed7901SPeter Brune 1408e4ed7901SPeter Brune Logically Collective on SNES 1409e4ed7901SPeter Brune 1410e4ed7901SPeter Brune Input Parameters: 1411e4ed7901SPeter Brune + snes - the SNES context 1412e4ed7901SPeter Brune - f - vector to store function value 1413e4ed7901SPeter Brune 1414e4ed7901SPeter Brune Notes: 1415e4ed7901SPeter Brune This should not be modified during the solution procedure. 1416e4ed7901SPeter Brune 1417e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1418e4ed7901SPeter Brune 1419e4ed7901SPeter Brune Level: developer 1420e4ed7901SPeter Brune 1421e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function 1422e4ed7901SPeter Brune 1423e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm() 1424e4ed7901SPeter Brune @*/ 1425e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1426e4ed7901SPeter Brune { 1427e4ed7901SPeter Brune PetscErrorCode ierr; 1428e4ed7901SPeter Brune Vec vec_func; 1429e4ed7901SPeter Brune 1430e4ed7901SPeter Brune PetscFunctionBegin; 1431e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1432e4ed7901SPeter Brune PetscValidHeaderSpecific(f,VEC_CLASSID,2); 1433e4ed7901SPeter Brune PetscCheckSameComm(snes,1,f,2); 1434e4ed7901SPeter Brune ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1435e4ed7901SPeter Brune ierr = VecCopy(f, vec_func);CHKERRQ(ierr); 1436217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 1437e4ed7901SPeter Brune PetscFunctionReturn(0); 1438e4ed7901SPeter Brune } 1439e4ed7901SPeter Brune 1440e4ed7901SPeter Brune 1441e4ed7901SPeter Brune #undef __FUNCT__ 1442e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm" 1443e4ed7901SPeter Brune /*@C 1444e4ed7901SPeter Brune SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm 1445e4ed7901SPeter Brune at the initialization of the method. In some instances, the user has precomputed 1446e4ed7901SPeter Brune the function and its norm before calling SNESSolve. This function allows one to 1447e4ed7901SPeter Brune avoid a redundant call to SNESComputeFunction() and VecNorm() in that case. 1448e4ed7901SPeter Brune 1449e4ed7901SPeter Brune Logically Collective on SNES 1450e4ed7901SPeter Brune 1451e4ed7901SPeter Brune Input Parameters: 1452e4ed7901SPeter Brune + snes - the SNES context 1453e4ed7901SPeter Brune - fnorm - the norm of F as set by SNESSetInitialFunction() 1454e4ed7901SPeter Brune 1455e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1456e4ed7901SPeter Brune 1457e4ed7901SPeter Brune Level: developer 1458e4ed7901SPeter Brune 1459e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm 1460e4ed7901SPeter Brune 1461e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction() 1462e4ed7901SPeter Brune @*/ 1463e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm) 1464e4ed7901SPeter Brune { 1465e4ed7901SPeter Brune PetscFunctionBegin; 1466e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1467e4ed7901SPeter Brune snes->norm_init = fnorm; 1468e4ed7901SPeter Brune snes->norm_init_set = PETSC_TRUE; 1469e4ed7901SPeter Brune PetscFunctionReturn(0); 1470e4ed7901SPeter Brune } 1471e4ed7901SPeter Brune 1472e4ed7901SPeter Brune #undef __FUNCT__ 1473534ebe21SPeter Brune #define __FUNCT__ "SNESSetNormType" 1474534ebe21SPeter Brune /*@ 1475534ebe21SPeter Brune SNESSetNormType - Sets the SNESNormType used in covergence and monitoring 1476534ebe21SPeter Brune of the SNES method. 1477534ebe21SPeter Brune 1478534ebe21SPeter Brune Logically Collective on SNES 1479534ebe21SPeter Brune 1480534ebe21SPeter Brune Input Parameters: 1481534ebe21SPeter Brune + snes - the SNES context 1482534ebe21SPeter Brune - normtype - the type of the norm used 1483534ebe21SPeter Brune 1484534ebe21SPeter Brune Notes: 1485534ebe21SPeter Brune Only certain SNES methods support certain SNESNormTypes. Most require evaluation 1486534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1487534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1488534ebe21SPeter Brune (SNESGS) and the like do not require the norm of the function to be computed, and therfore 1489534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1490534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1491534ebe21SPeter Brune their solution. 1492534ebe21SPeter Brune 1493534ebe21SPeter Brune Level: developer 1494534ebe21SPeter Brune 1495534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1496534ebe21SPeter Brune 1497534ebe21SPeter Brune .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType 1498534ebe21SPeter Brune @*/ 1499534ebe21SPeter Brune PetscErrorCode SNESSetNormType(SNES snes, SNESNormType normtype) 1500534ebe21SPeter Brune { 1501534ebe21SPeter Brune PetscFunctionBegin; 1502534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1503534ebe21SPeter Brune snes->normtype = normtype; 1504534ebe21SPeter Brune PetscFunctionReturn(0); 1505534ebe21SPeter Brune } 1506534ebe21SPeter Brune 1507534ebe21SPeter Brune 1508534ebe21SPeter Brune #undef __FUNCT__ 1509534ebe21SPeter Brune #define __FUNCT__ "SNESGetNormType" 1510534ebe21SPeter Brune /*@ 1511534ebe21SPeter Brune SNESGetNormType - Gets the SNESNormType used in covergence and monitoring 1512534ebe21SPeter Brune of the SNES method. 1513534ebe21SPeter Brune 1514534ebe21SPeter Brune Logically Collective on SNES 1515534ebe21SPeter Brune 1516534ebe21SPeter Brune Input Parameters: 1517534ebe21SPeter Brune + snes - the SNES context 1518534ebe21SPeter Brune - normtype - the type of the norm used 1519534ebe21SPeter Brune 1520534ebe21SPeter Brune Level: advanced 1521534ebe21SPeter Brune 1522534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1523534ebe21SPeter Brune 1524534ebe21SPeter Brune .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType 1525534ebe21SPeter Brune @*/ 1526534ebe21SPeter Brune PetscErrorCode SNESGetNormType(SNES snes, SNESNormType *normtype) 1527534ebe21SPeter Brune { 1528534ebe21SPeter Brune PetscFunctionBegin; 1529534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1530534ebe21SPeter Brune *normtype = snes->normtype; 1531534ebe21SPeter Brune PetscFunctionReturn(0); 1532534ebe21SPeter Brune } 1533534ebe21SPeter Brune 1534534ebe21SPeter Brune #undef __FUNCT__ 1535646217ecSPeter Brune #define __FUNCT__ "SNESSetGS" 1536c79ef259SPeter Brune /*@C 1537c79ef259SPeter Brune SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for 1538c79ef259SPeter Brune use with composed nonlinear solvers. 1539c79ef259SPeter Brune 1540c79ef259SPeter Brune Input Parameters: 1541c79ef259SPeter Brune + snes - the SNES context 1542c79ef259SPeter Brune . gsfunc - function evaluation routine 1543c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 1544c79ef259SPeter Brune smoother evaluation routine (may be PETSC_NULL) 1545c79ef259SPeter Brune 1546c79ef259SPeter Brune Calling sequence of func: 1547c79ef259SPeter Brune $ func (SNES snes,Vec x,Vec b,void *ctx); 1548c79ef259SPeter Brune 1549c79ef259SPeter Brune + X - solution vector 1550c79ef259SPeter Brune . B - RHS vector 1551d28543b3SPeter Brune - ctx - optional user-defined Gauss-Seidel context 1552c79ef259SPeter Brune 1553c79ef259SPeter Brune Notes: 1554c79ef259SPeter Brune The GS routines are used by the composed nonlinear solver to generate 1555c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1556c79ef259SPeter Brune 1557d28543b3SPeter Brune Level: intermediate 1558c79ef259SPeter Brune 1559d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1560c79ef259SPeter Brune 1561c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS() 1562c79ef259SPeter Brune @*/ 15636cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx) 15646cab3a1bSJed Brown { 15656cab3a1bSJed Brown PetscErrorCode ierr; 15666cab3a1bSJed Brown DM dm; 15676cab3a1bSJed Brown 1568646217ecSPeter Brune PetscFunctionBegin; 15696cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15706cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 15716cab3a1bSJed Brown ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr); 1572646217ecSPeter Brune PetscFunctionReturn(0); 1573646217ecSPeter Brune } 1574646217ecSPeter Brune 1575d25893d9SBarry Smith #undef __FUNCT__ 157689b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps" 157789b92e6fSPeter Brune /*@ 157889b92e6fSPeter Brune SNESSetGSSweeps - Sets the number of sweeps of GS to use. 157989b92e6fSPeter Brune 158089b92e6fSPeter Brune Input Parameters: 158189b92e6fSPeter Brune + snes - the SNES context 158289b92e6fSPeter Brune - sweeps - the number of sweeps of GS to perform. 158389b92e6fSPeter Brune 158489b92e6fSPeter Brune Level: intermediate 158589b92e6fSPeter Brune 158689b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 158789b92e6fSPeter Brune 158889b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps() 158989b92e6fSPeter Brune @*/ 159089b92e6fSPeter Brune 159189b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) { 159289b92e6fSPeter Brune PetscFunctionBegin; 159389b92e6fSPeter Brune snes->gssweeps = sweeps; 159489b92e6fSPeter Brune PetscFunctionReturn(0); 159589b92e6fSPeter Brune } 159689b92e6fSPeter Brune 159789b92e6fSPeter Brune 159889b92e6fSPeter Brune #undef __FUNCT__ 159989b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps" 160089b92e6fSPeter Brune /*@ 160189b92e6fSPeter Brune SNESGetGSSweeps - Gets the number of sweeps GS will use. 160289b92e6fSPeter Brune 160389b92e6fSPeter Brune Input Parameters: 160489b92e6fSPeter Brune . snes - the SNES context 160589b92e6fSPeter Brune 160689b92e6fSPeter Brune Output Parameters: 160789b92e6fSPeter Brune . sweeps - the number of sweeps of GS to perform. 160889b92e6fSPeter Brune 160989b92e6fSPeter Brune Level: intermediate 161089b92e6fSPeter Brune 161189b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 161289b92e6fSPeter Brune 161389b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps() 161489b92e6fSPeter Brune @*/ 161589b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) { 161689b92e6fSPeter Brune PetscFunctionBegin; 161789b92e6fSPeter Brune *sweeps = snes->gssweeps; 161889b92e6fSPeter Brune PetscFunctionReturn(0); 161989b92e6fSPeter Brune } 162089b92e6fSPeter Brune 162189b92e6fSPeter Brune #undef __FUNCT__ 16228b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 16238b0a5094SBarry Smith PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 16248b0a5094SBarry Smith { 16258b0a5094SBarry Smith PetscErrorCode ierr; 16266cab3a1bSJed Brown void *functx,*jacctx; 16276cab3a1bSJed Brown 16288b0a5094SBarry Smith PetscFunctionBegin; 16296cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 16306cab3a1bSJed Brown ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr); 16318b0a5094SBarry Smith /* A(x)*x - b(x) */ 16326cab3a1bSJed Brown ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr); 16336cab3a1bSJed Brown ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr); 16348b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 16358b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 16368b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 16378b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 16388b0a5094SBarry Smith PetscFunctionReturn(0); 16398b0a5094SBarry Smith } 16408b0a5094SBarry Smith 16418b0a5094SBarry Smith #undef __FUNCT__ 16428b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 16438b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 16448b0a5094SBarry Smith { 16458b0a5094SBarry Smith PetscFunctionBegin; 16468b0a5094SBarry Smith *flag = snes->matstruct; 16478b0a5094SBarry Smith PetscFunctionReturn(0); 16488b0a5094SBarry Smith } 16498b0a5094SBarry Smith 16508b0a5094SBarry Smith #undef __FUNCT__ 16518b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 16528b0a5094SBarry Smith /*@C 16530d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 16548b0a5094SBarry Smith 16558b0a5094SBarry Smith Logically Collective on SNES 16568b0a5094SBarry Smith 16578b0a5094SBarry Smith Input Parameters: 16588b0a5094SBarry Smith + snes - the SNES context 16598b0a5094SBarry Smith . r - vector to store function value 16608b0a5094SBarry Smith . func - function evaluation routine 16618b0a5094SBarry 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) 16628b0a5094SBarry Smith . mat - matrix to store A 16638b0a5094SBarry Smith . mfunc - function to compute matrix value 16648b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 16658b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 16668b0a5094SBarry Smith 16678b0a5094SBarry Smith Calling sequence of func: 16688b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 16698b0a5094SBarry Smith 16708b0a5094SBarry Smith + f - function vector 16718b0a5094SBarry Smith - ctx - optional user-defined function context 16728b0a5094SBarry Smith 16738b0a5094SBarry Smith Calling sequence of mfunc: 16748b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 16758b0a5094SBarry Smith 16768b0a5094SBarry Smith + x - input vector 16778b0a5094SBarry 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(), 16788b0a5094SBarry Smith normally just pass mat in this location 16798b0a5094SBarry Smith . mat - form A(x) matrix 16808b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 16818b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 16828b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 16838b0a5094SBarry Smith 16848b0a5094SBarry Smith Notes: 16858b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 16868b0a5094SBarry Smith 16878b0a5094SBarry 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} 16888b0a5094SBarry 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. 16898b0a5094SBarry Smith 16908b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 16918b0a5094SBarry Smith 16920d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 16930d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 16948b0a5094SBarry Smith 16958b0a5094SBarry 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 16968b0a5094SBarry 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 16978b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 16988b0a5094SBarry Smith 16998b0a5094SBarry Smith Level: beginner 17008b0a5094SBarry Smith 17018b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 17028b0a5094SBarry Smith 17030d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard() 17048b0a5094SBarry Smith @*/ 17058b0a5094SBarry 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) 17068b0a5094SBarry Smith { 17078b0a5094SBarry Smith PetscErrorCode ierr; 17088b0a5094SBarry Smith PetscFunctionBegin; 17098b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 17108b0a5094SBarry Smith snes->ops->computepfunction = func; 17118b0a5094SBarry Smith snes->ops->computepjacobian = mfunc; 17128b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 17138b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 17148b0a5094SBarry Smith PetscFunctionReturn(0); 17158b0a5094SBarry Smith } 17168b0a5094SBarry Smith 17178b0a5094SBarry Smith #undef __FUNCT__ 1718d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1719d25893d9SBarry Smith /*@C 1720d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1721d25893d9SBarry Smith 1722d25893d9SBarry Smith Logically Collective on SNES 1723d25893d9SBarry Smith 1724d25893d9SBarry Smith Input Parameters: 1725d25893d9SBarry Smith + snes - the SNES context 1726d25893d9SBarry Smith . func - function evaluation routine 1727d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1728d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1729d25893d9SBarry Smith 1730d25893d9SBarry Smith Calling sequence of func: 1731d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1732d25893d9SBarry Smith 1733d25893d9SBarry Smith . f - function vector 1734d25893d9SBarry Smith - ctx - optional user-defined function context 1735d25893d9SBarry Smith 1736d25893d9SBarry Smith Level: intermediate 1737d25893d9SBarry Smith 1738d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1739d25893d9SBarry Smith 1740d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1741d25893d9SBarry Smith @*/ 1742d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1743d25893d9SBarry Smith { 1744d25893d9SBarry Smith PetscFunctionBegin; 1745d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1746d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1747d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1748d25893d9SBarry Smith PetscFunctionReturn(0); 1749d25893d9SBarry Smith } 1750d25893d9SBarry Smith 17513ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 17523ab0aad5SBarry Smith #undef __FUNCT__ 17531096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 17541096aae1SMatthew Knepley /*@C 17551096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 17561096aae1SMatthew Knepley it assumes a zero right hand side. 17571096aae1SMatthew Knepley 17583f9fe445SBarry Smith Logically Collective on SNES 17591096aae1SMatthew Knepley 17601096aae1SMatthew Knepley Input Parameter: 17611096aae1SMatthew Knepley . snes - the SNES context 17621096aae1SMatthew Knepley 17631096aae1SMatthew Knepley Output Parameter: 1764bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 17651096aae1SMatthew Knepley 17661096aae1SMatthew Knepley Level: intermediate 17671096aae1SMatthew Knepley 17681096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 17691096aae1SMatthew Knepley 177085385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 17711096aae1SMatthew Knepley @*/ 17727087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 17731096aae1SMatthew Knepley { 17741096aae1SMatthew Knepley PetscFunctionBegin; 17750700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 17761096aae1SMatthew Knepley PetscValidPointer(rhs,2); 177785385478SLisandro Dalcin *rhs = snes->vec_rhs; 17781096aae1SMatthew Knepley PetscFunctionReturn(0); 17791096aae1SMatthew Knepley } 17801096aae1SMatthew Knepley 17811096aae1SMatthew Knepley #undef __FUNCT__ 17824a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 17839b94acceSBarry Smith /*@ 178436851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 17859b94acceSBarry Smith SNESSetFunction(). 17869b94acceSBarry Smith 1787c7afd0dbSLois Curfman McInnes Collective on SNES 1788c7afd0dbSLois Curfman McInnes 17899b94acceSBarry Smith Input Parameters: 1790c7afd0dbSLois Curfman McInnes + snes - the SNES context 1791c7afd0dbSLois Curfman McInnes - x - input vector 17929b94acceSBarry Smith 17939b94acceSBarry Smith Output Parameter: 17943638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 17959b94acceSBarry Smith 17961bffabb2SLois Curfman McInnes Notes: 179736851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 179836851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 179936851e7fSLois Curfman McInnes themselves. 180036851e7fSLois Curfman McInnes 180136851e7fSLois Curfman McInnes Level: developer 180236851e7fSLois Curfman McInnes 18039b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 18049b94acceSBarry Smith 1805a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 18069b94acceSBarry Smith @*/ 18077087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 18089b94acceSBarry Smith { 1809dfbe8321SBarry Smith PetscErrorCode ierr; 18106cab3a1bSJed Brown DM dm; 18116cab3a1bSJed Brown SNESDM sdm; 18129b94acceSBarry Smith 18133a40ed3dSBarry Smith PetscFunctionBegin; 18140700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 18150700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 18160700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1817c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1818c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 18194ec14c9cSBarry Smith VecValidValues(x,2,PETSC_TRUE); 1820184914b5SBarry Smith 18216cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18226cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 1823d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 18246cab3a1bSJed Brown if (sdm->computefunction) { 1825d64ed03dSBarry Smith PetscStackPush("SNES user function"); 18266cab3a1bSJed Brown ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 1827d64ed03dSBarry Smith PetscStackPop; 182873250ac0SBarry Smith } else if (snes->dm) { 1829644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1830c90fad12SPeter Brune } else if (snes->vec_rhs) { 1831c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1832644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 183385385478SLisandro Dalcin if (snes->vec_rhs) { 183485385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 18353ab0aad5SBarry Smith } 1836ae3c334cSLois Curfman McInnes snes->nfuncs++; 1837d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 18384ec14c9cSBarry Smith VecValidValues(y,3,PETSC_FALSE); 18393a40ed3dSBarry Smith PetscFunctionReturn(0); 18409b94acceSBarry Smith } 18419b94acceSBarry Smith 18424a2ae208SSatish Balay #undef __FUNCT__ 1843646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1844c79ef259SPeter Brune /*@ 1845c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1846c79ef259SPeter Brune SNESSetGS(). 1847c79ef259SPeter Brune 1848c79ef259SPeter Brune Collective on SNES 1849c79ef259SPeter Brune 1850c79ef259SPeter Brune Input Parameters: 1851c79ef259SPeter Brune + snes - the SNES context 1852c79ef259SPeter Brune . x - input vector 1853c79ef259SPeter Brune - b - rhs vector 1854c79ef259SPeter Brune 1855c79ef259SPeter Brune Output Parameter: 1856c79ef259SPeter Brune . x - new solution vector 1857c79ef259SPeter Brune 1858c79ef259SPeter Brune Notes: 1859c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1860c79ef259SPeter Brune implementations, so most users would not generally call this routine 1861c79ef259SPeter Brune themselves. 1862c79ef259SPeter Brune 1863c79ef259SPeter Brune Level: developer 1864c79ef259SPeter Brune 1865c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1866c79ef259SPeter Brune 1867c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1868c79ef259SPeter Brune @*/ 1869646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1870646217ecSPeter Brune { 1871646217ecSPeter Brune PetscErrorCode ierr; 187289b92e6fSPeter Brune PetscInt i; 18736cab3a1bSJed Brown DM dm; 18746cab3a1bSJed Brown SNESDM sdm; 1875646217ecSPeter Brune 1876646217ecSPeter Brune PetscFunctionBegin; 1877646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1878646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1879646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1880646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 1881646217ecSPeter Brune if(b) PetscCheckSameComm(snes,1,b,3); 18824ec14c9cSBarry Smith if (b) VecValidValues(b,2,PETSC_TRUE); 1883701cf23dSPeter Brune ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 18846cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18856cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 18866cab3a1bSJed Brown if (sdm->computegs) { 188789b92e6fSPeter Brune for (i = 0; i < snes->gssweeps; i++) { 1888646217ecSPeter Brune PetscStackPush("SNES user GS"); 18896cab3a1bSJed Brown ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 1890646217ecSPeter Brune PetscStackPop; 189189b92e6fSPeter Brune } 1892646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 1893701cf23dSPeter Brune ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 18944ec14c9cSBarry Smith VecValidValues(x,3,PETSC_FALSE); 1895646217ecSPeter Brune PetscFunctionReturn(0); 1896646217ecSPeter Brune } 1897646217ecSPeter Brune 1898646217ecSPeter Brune 1899646217ecSPeter Brune #undef __FUNCT__ 19004a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 190162fef451SLois Curfman McInnes /*@ 190262fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 190362fef451SLois Curfman McInnes set with SNESSetJacobian(). 190462fef451SLois Curfman McInnes 1905c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1906c7afd0dbSLois Curfman McInnes 190762fef451SLois Curfman McInnes Input Parameters: 1908c7afd0dbSLois Curfman McInnes + snes - the SNES context 1909c7afd0dbSLois Curfman McInnes - x - input vector 191062fef451SLois Curfman McInnes 191162fef451SLois Curfman McInnes Output Parameters: 1912c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 191362fef451SLois Curfman McInnes . B - optional preconditioning matrix 19142b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1915fee21e36SBarry Smith 1916e35cf81dSBarry Smith Options Database Keys: 1917e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1918693365a8SJed Brown . -snes_lag_jacobian <lag> 1919693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1920693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1921693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 19224c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1923c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 1924c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 1925c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 1926c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 1927c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 19284c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 1929c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 1930c01495d3SJed Brown 1931e35cf81dSBarry Smith 193262fef451SLois Curfman McInnes Notes: 193362fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 193462fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 193562fef451SLois Curfman McInnes 193694b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1937dc5a77f8SLois Curfman McInnes flag parameter. 193862fef451SLois Curfman McInnes 193936851e7fSLois Curfman McInnes Level: developer 194036851e7fSLois Curfman McInnes 194162fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 194262fef451SLois Curfman McInnes 1943e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 194462fef451SLois Curfman McInnes @*/ 19457087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 19469b94acceSBarry Smith { 1947dfbe8321SBarry Smith PetscErrorCode ierr; 1948ace3abfcSBarry Smith PetscBool flag; 19496cab3a1bSJed Brown DM dm; 19506cab3a1bSJed Brown SNESDM sdm; 19513a40ed3dSBarry Smith 19523a40ed3dSBarry Smith PetscFunctionBegin; 19530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 19540700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 19554482741eSBarry Smith PetscValidPointer(flg,5); 1956c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 19574ec14c9cSBarry Smith VecValidValues(X,2,PETSC_TRUE); 19586cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 19596cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 19606cab3a1bSJed Brown if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 1961ebd3b9afSBarry Smith 1962ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1963ebd3b9afSBarry Smith 1964fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 1965fe3ffe1eSBarry Smith snes->lagjacobian = -1; 1966fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1967fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 1968e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1969e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1970251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1971ebd3b9afSBarry Smith if (flag) { 1972ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1973ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1974ebd3b9afSBarry Smith } 1975e35cf81dSBarry Smith PetscFunctionReturn(0); 1976e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1977e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1978e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1979251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1980ebd3b9afSBarry Smith if (flag) { 1981ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1982ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1983ebd3b9afSBarry Smith } 1984e35cf81dSBarry Smith PetscFunctionReturn(0); 1985e35cf81dSBarry Smith } 1986e35cf81dSBarry Smith 1987c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 1988e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1989d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 19906cab3a1bSJed Brown ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr); 1991d64ed03dSBarry Smith PetscStackPop; 1992d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1993a8054027SBarry Smith 19943b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 19953b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 19963b4f5425SBarry Smith snes->lagpreconditioner = -1; 19973b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 1998a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1999a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 2000a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 2001a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 2002a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 2003a8054027SBarry Smith } 2004a8054027SBarry Smith 20056d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 20060700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 20070700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 2008693365a8SJed Brown { 2009693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 2010693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 2011693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 2012693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 2013693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 2014693365a8SJed Brown if (flag || flag_draw || flag_contour) { 2015693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 2016693365a8SJed Brown MatStructure mstruct; 2017693365a8SJed Brown PetscViewer vdraw,vstdout; 20186b3a5b13SJed Brown PetscBool flg; 2019693365a8SJed Brown if (flag_operator) { 2020693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 2021693365a8SJed Brown Bexp = Bexp_mine; 2022693365a8SJed Brown } else { 2023693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 2024251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 2025693365a8SJed Brown if (flg) Bexp = *B; 2026693365a8SJed Brown else { 2027693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 2028693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 2029693365a8SJed Brown Bexp = Bexp_mine; 2030693365a8SJed Brown } 2031693365a8SJed Brown } 2032693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 2033693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 2034693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 2035693365a8SJed Brown if (flag_draw || flag_contour) { 2036693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2037693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 2038693365a8SJed Brown } else vdraw = PETSC_NULL; 2039693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 2040693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 2041693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 2042693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 2043693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2044693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 2045693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2046693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 2047693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2048693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 2049693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2050693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 2051693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2052693365a8SJed Brown } 2053693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2054693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2055693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 2056693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 2057693365a8SJed Brown } 2058693365a8SJed Brown } 20594c30e9fbSJed Brown { 20606719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 20616719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 20624c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 20636719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 20644c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 20654c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 20666719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 20676719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 20686719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 20696719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 20704c30e9fbSJed Brown Mat Bfd; 20714c30e9fbSJed Brown MatStructure mstruct; 20724c30e9fbSJed Brown PetscViewer vdraw,vstdout; 20734c30e9fbSJed Brown ISColoring iscoloring; 20744c30e9fbSJed Brown MatFDColoring matfdcoloring; 20754c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 20764c30e9fbSJed Brown void *funcctx; 20776719d8e4SJed Brown PetscReal norm1,norm2,normmax; 20784c30e9fbSJed Brown 20794c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 20804c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 20814c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 20824c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 20834c30e9fbSJed Brown 20844c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 20854c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 20864c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 20874c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 20884c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 20894c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 20904c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 20914c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 20924c30e9fbSJed Brown 20934c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 20944c30e9fbSJed Brown if (flag_draw || flag_contour) { 20954c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 20964c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 20974c30e9fbSJed Brown } else vdraw = PETSC_NULL; 20984c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 20996719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 21004c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 21014c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 21026719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 21034c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 21044c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 21054c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 21066719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 21074c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 21086719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 21096719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 21104c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 21114c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 21124c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 21134c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 21144c30e9fbSJed Brown } 21154c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 21166719d8e4SJed Brown 21176719d8e4SJed Brown if (flag_threshold) { 21186719d8e4SJed Brown PetscInt bs,rstart,rend,i; 21196719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 21206719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 21216719d8e4SJed Brown for (i=rstart; i<rend; i++) { 21226719d8e4SJed Brown const PetscScalar *ba,*ca; 21236719d8e4SJed Brown const PetscInt *bj,*cj; 21246719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 21256719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 21266719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 21276719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 21286719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 21296719d8e4SJed Brown for (j=0; j<bn; j++) { 21306719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 21316719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 21326719d8e4SJed Brown maxentrycol = bj[j]; 21336719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 21346719d8e4SJed Brown } 21356719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 21366719d8e4SJed Brown maxdiffcol = bj[j]; 21376719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 21386719d8e4SJed Brown } 21396719d8e4SJed Brown if (rdiff > maxrdiff) { 21406719d8e4SJed Brown maxrdiffcol = bj[j]; 21416719d8e4SJed Brown maxrdiff = rdiff; 21426719d8e4SJed Brown } 21436719d8e4SJed Brown } 21446719d8e4SJed Brown if (maxrdiff > 1) { 21456719d8e4SJed 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); 21466719d8e4SJed Brown for (j=0; j<bn; j++) { 21476719d8e4SJed Brown PetscReal rdiff; 21486719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 21496719d8e4SJed Brown if (rdiff > 1) { 21506719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 21516719d8e4SJed Brown } 21526719d8e4SJed Brown } 21536719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 21546719d8e4SJed Brown } 21556719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 21566719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 21576719d8e4SJed Brown } 21586719d8e4SJed Brown } 21594c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 21604c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 21614c30e9fbSJed Brown } 21624c30e9fbSJed Brown } 21633a40ed3dSBarry Smith PetscFunctionReturn(0); 21649b94acceSBarry Smith } 21659b94acceSBarry Smith 21664a2ae208SSatish Balay #undef __FUNCT__ 21674a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 21689b94acceSBarry Smith /*@C 21699b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2170044dda88SLois Curfman McInnes location to store the matrix. 21719b94acceSBarry Smith 21723f9fe445SBarry Smith Logically Collective on SNES and Mat 2173c7afd0dbSLois Curfman McInnes 21749b94acceSBarry Smith Input Parameters: 2175c7afd0dbSLois Curfman McInnes + snes - the SNES context 21769b94acceSBarry Smith . A - Jacobian matrix 21779b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 2178efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 2179c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 2180efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 21819b94acceSBarry Smith 21829b94acceSBarry Smith Calling sequence of func: 21838d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 21849b94acceSBarry Smith 2185c7afd0dbSLois Curfman McInnes + x - input vector 21869b94acceSBarry Smith . A - Jacobian matrix 21879b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 2188ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 21892b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 2190c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 21919b94acceSBarry Smith 21929b94acceSBarry Smith Notes: 219394b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 21942cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 2195ac21db08SLois Curfman McInnes 2196ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 21979b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 21989b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 21999b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 22009b94acceSBarry Smith throughout the global iterations. 22019b94acceSBarry Smith 220216913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 220316913363SBarry Smith each matrix. 220416913363SBarry Smith 2205a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 2206a8a26c1eSJed Brown must be a MatFDColoring. 2207a8a26c1eSJed Brown 2208c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2209c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2210c3cc8fd1SJed Brown 221136851e7fSLois Curfman McInnes Level: beginner 221236851e7fSLois Curfman McInnes 22139b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 22149b94acceSBarry Smith 22153ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 22169b94acceSBarry Smith @*/ 22177087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 22189b94acceSBarry Smith { 2219dfbe8321SBarry Smith PetscErrorCode ierr; 22206cab3a1bSJed Brown DM dm; 22213a7fca6bSBarry Smith 22223a40ed3dSBarry Smith PetscFunctionBegin; 22230700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 22240700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 22250700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 2226c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 222706975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 22286cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 22296cab3a1bSJed Brown ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr); 22303a7fca6bSBarry Smith if (A) { 22317dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 22326bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 22339b94acceSBarry Smith snes->jacobian = A; 22343a7fca6bSBarry Smith } 22353a7fca6bSBarry Smith if (B) { 22367dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 22376bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 22389b94acceSBarry Smith snes->jacobian_pre = B; 22393a7fca6bSBarry Smith } 22403a40ed3dSBarry Smith PetscFunctionReturn(0); 22419b94acceSBarry Smith } 224262fef451SLois Curfman McInnes 22434a2ae208SSatish Balay #undef __FUNCT__ 22444a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 2245c2aafc4cSSatish Balay /*@C 2246b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2247b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2248b4fd4287SBarry Smith 2249c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2250c7afd0dbSLois Curfman McInnes 2251b4fd4287SBarry Smith Input Parameter: 2252b4fd4287SBarry Smith . snes - the nonlinear solver context 2253b4fd4287SBarry Smith 2254b4fd4287SBarry Smith Output Parameters: 2255c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 2256b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 225770e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 225870e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 2259fee21e36SBarry Smith 226036851e7fSLois Curfman McInnes Level: advanced 226136851e7fSLois Curfman McInnes 2262b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 2263b4fd4287SBarry Smith @*/ 22647087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 2265b4fd4287SBarry Smith { 22666cab3a1bSJed Brown PetscErrorCode ierr; 22676cab3a1bSJed Brown DM dm; 22686cab3a1bSJed Brown SNESDM sdm; 22696cab3a1bSJed Brown 22703a40ed3dSBarry Smith PetscFunctionBegin; 22710700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2272b4fd4287SBarry Smith if (A) *A = snes->jacobian; 2273b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 22746cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 22756cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 22766cab3a1bSJed Brown if (func) *func = sdm->computejacobian; 22776cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 22783a40ed3dSBarry Smith PetscFunctionReturn(0); 2279b4fd4287SBarry Smith } 2280b4fd4287SBarry Smith 22819b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 22829b94acceSBarry Smith 22834a2ae208SSatish Balay #undef __FUNCT__ 22844a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 22859b94acceSBarry Smith /*@ 22869b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2287272ac6f2SLois Curfman McInnes of a nonlinear solver. 22889b94acceSBarry Smith 2289fee21e36SBarry Smith Collective on SNES 2290fee21e36SBarry Smith 2291c7afd0dbSLois Curfman McInnes Input Parameters: 229270e92668SMatthew Knepley . snes - the SNES context 2293c7afd0dbSLois Curfman McInnes 2294272ac6f2SLois Curfman McInnes Notes: 2295272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2296272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2297272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2298272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2299272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2300272ac6f2SLois Curfman McInnes 230136851e7fSLois Curfman McInnes Level: advanced 230236851e7fSLois Curfman McInnes 23039b94acceSBarry Smith .keywords: SNES, nonlinear, setup 23049b94acceSBarry Smith 23059b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 23069b94acceSBarry Smith @*/ 23077087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 23089b94acceSBarry Smith { 2309dfbe8321SBarry Smith PetscErrorCode ierr; 23106cab3a1bSJed Brown DM dm; 23116cab3a1bSJed Brown SNESDM sdm; 23123a40ed3dSBarry Smith 23133a40ed3dSBarry Smith PetscFunctionBegin; 23140700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23154dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 23169b94acceSBarry Smith 23177adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 231885385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 231985385478SLisandro Dalcin } 232085385478SLisandro Dalcin 2321a63bb30eSJed Brown ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 232217186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 232358c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 232458c9b817SLisandro Dalcin 232558c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 232658c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 232758c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 232858c9b817SLisandro Dalcin } 232958c9b817SLisandro Dalcin 23306cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 23316cab3a1bSJed Brown ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */ 23326cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 23336cab3a1bSJed Brown if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc"); 23346cab3a1bSJed Brown if (!snes->vec_func) { 23356cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2336214df951SJed Brown } 2337efd51863SBarry Smith 2338b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 2339b710008aSBarry Smith 2340f1c6b773SPeter Brune if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);} 23419e764e56SPeter Brune 2342d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 2343d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2344d25893d9SBarry Smith } 2345d25893d9SBarry Smith 2346410397dcSLisandro Dalcin if (snes->ops->setup) { 2347410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2348410397dcSLisandro Dalcin } 234958c9b817SLisandro Dalcin 23507aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 23513a40ed3dSBarry Smith PetscFunctionReturn(0); 23529b94acceSBarry Smith } 23539b94acceSBarry Smith 23544a2ae208SSatish Balay #undef __FUNCT__ 235537596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 235637596af1SLisandro Dalcin /*@ 235737596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 235837596af1SLisandro Dalcin 235937596af1SLisandro Dalcin Collective on SNES 236037596af1SLisandro Dalcin 236137596af1SLisandro Dalcin Input Parameter: 236237596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 236337596af1SLisandro Dalcin 2364d25893d9SBarry Smith Level: intermediate 2365d25893d9SBarry Smith 2366d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 236737596af1SLisandro Dalcin 236837596af1SLisandro Dalcin .keywords: SNES, destroy 236937596af1SLisandro Dalcin 237037596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 237137596af1SLisandro Dalcin @*/ 237237596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 237337596af1SLisandro Dalcin { 237437596af1SLisandro Dalcin PetscErrorCode ierr; 237537596af1SLisandro Dalcin 237637596af1SLisandro Dalcin PetscFunctionBegin; 237737596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2378d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2379d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2380d25893d9SBarry Smith snes->user = PETSC_NULL; 2381d25893d9SBarry Smith } 23828a23116dSBarry Smith if (snes->pc) { 23838a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 23848a23116dSBarry Smith } 23858a23116dSBarry Smith 238637596af1SLisandro Dalcin if (snes->ops->reset) { 238737596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 238837596af1SLisandro Dalcin } 23899e764e56SPeter Brune if (snes->ksp) { 23909e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 23919e764e56SPeter Brune } 23929e764e56SPeter Brune 23939e764e56SPeter Brune if (snes->linesearch) { 2394f1c6b773SPeter Brune ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 23959e764e56SPeter Brune } 23969e764e56SPeter Brune 23976bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 23986bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 23996bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 24006bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 24016bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 24026bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2403c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2404c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 240537596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 240637596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 240737596af1SLisandro Dalcin PetscFunctionReturn(0); 240837596af1SLisandro Dalcin } 240937596af1SLisandro Dalcin 241037596af1SLisandro Dalcin #undef __FUNCT__ 24114a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 241252baeb72SSatish Balay /*@ 24139b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 24149b94acceSBarry Smith with SNESCreate(). 24159b94acceSBarry Smith 2416c7afd0dbSLois Curfman McInnes Collective on SNES 2417c7afd0dbSLois Curfman McInnes 24189b94acceSBarry Smith Input Parameter: 24199b94acceSBarry Smith . snes - the SNES context 24209b94acceSBarry Smith 242136851e7fSLois Curfman McInnes Level: beginner 242236851e7fSLois Curfman McInnes 24239b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 24249b94acceSBarry Smith 242563a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 24269b94acceSBarry Smith @*/ 24276bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 24289b94acceSBarry Smith { 24296849ba73SBarry Smith PetscErrorCode ierr; 24303a40ed3dSBarry Smith 24313a40ed3dSBarry Smith PetscFunctionBegin; 24326bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 24336bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 24346bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2435d4bb536fSBarry Smith 24366bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 24378a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 24386b8b9a38SLisandro Dalcin 2439be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 24406bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 24416bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 24426d4c513bSLisandro Dalcin 24436bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 24446bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 2445f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 24466b8b9a38SLisandro Dalcin 24476bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 24486bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 24496bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 24506b8b9a38SLisandro Dalcin } 24516bf464f9SBarry Smith if ((*snes)->conv_malloc) { 24526bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 24536bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 245458c9b817SLisandro Dalcin } 24556bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2456a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 24573a40ed3dSBarry Smith PetscFunctionReturn(0); 24589b94acceSBarry Smith } 24599b94acceSBarry Smith 24609b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 24619b94acceSBarry Smith 24624a2ae208SSatish Balay #undef __FUNCT__ 2463a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2464a8054027SBarry Smith /*@ 2465a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2466a8054027SBarry Smith 24673f9fe445SBarry Smith Logically Collective on SNES 2468a8054027SBarry Smith 2469a8054027SBarry Smith Input Parameters: 2470a8054027SBarry Smith + snes - the SNES context 2471a8054027SBarry 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 24723b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2473a8054027SBarry Smith 2474a8054027SBarry Smith Options Database Keys: 2475a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2476a8054027SBarry Smith 2477a8054027SBarry Smith Notes: 2478a8054027SBarry Smith The default is 1 2479a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2480a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2481a8054027SBarry Smith 2482a8054027SBarry Smith Level: intermediate 2483a8054027SBarry Smith 2484a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2485a8054027SBarry Smith 2486e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2487a8054027SBarry Smith 2488a8054027SBarry Smith @*/ 24897087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2490a8054027SBarry Smith { 2491a8054027SBarry Smith PetscFunctionBegin; 24920700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2493e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2494e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2495c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2496a8054027SBarry Smith snes->lagpreconditioner = lag; 2497a8054027SBarry Smith PetscFunctionReturn(0); 2498a8054027SBarry Smith } 2499a8054027SBarry Smith 2500a8054027SBarry Smith #undef __FUNCT__ 2501efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2502efd51863SBarry Smith /*@ 2503efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2504efd51863SBarry Smith 2505efd51863SBarry Smith Logically Collective on SNES 2506efd51863SBarry Smith 2507efd51863SBarry Smith Input Parameters: 2508efd51863SBarry Smith + snes - the SNES context 2509efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2510efd51863SBarry Smith 2511efd51863SBarry Smith Options Database Keys: 2512efd51863SBarry Smith . -snes_grid_sequence <steps> 2513efd51863SBarry Smith 2514efd51863SBarry Smith Level: intermediate 2515efd51863SBarry Smith 2516c0df2a02SJed Brown Notes: 2517c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2518c0df2a02SJed Brown 2519efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2520efd51863SBarry Smith 2521efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2522efd51863SBarry Smith 2523efd51863SBarry Smith @*/ 2524efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2525efd51863SBarry Smith { 2526efd51863SBarry Smith PetscFunctionBegin; 2527efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2528efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2529efd51863SBarry Smith snes->gridsequence = steps; 2530efd51863SBarry Smith PetscFunctionReturn(0); 2531efd51863SBarry Smith } 2532efd51863SBarry Smith 2533efd51863SBarry Smith #undef __FUNCT__ 2534a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2535a8054027SBarry Smith /*@ 2536a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2537a8054027SBarry Smith 25383f9fe445SBarry Smith Not Collective 2539a8054027SBarry Smith 2540a8054027SBarry Smith Input Parameter: 2541a8054027SBarry Smith . snes - the SNES context 2542a8054027SBarry Smith 2543a8054027SBarry Smith Output Parameter: 2544a8054027SBarry 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 25453b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2546a8054027SBarry Smith 2547a8054027SBarry Smith Options Database Keys: 2548a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2549a8054027SBarry Smith 2550a8054027SBarry Smith Notes: 2551a8054027SBarry Smith The default is 1 2552a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2553a8054027SBarry Smith 2554a8054027SBarry Smith Level: intermediate 2555a8054027SBarry Smith 2556a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2557a8054027SBarry Smith 2558a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2559a8054027SBarry Smith 2560a8054027SBarry Smith @*/ 25617087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2562a8054027SBarry Smith { 2563a8054027SBarry Smith PetscFunctionBegin; 25640700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2565a8054027SBarry Smith *lag = snes->lagpreconditioner; 2566a8054027SBarry Smith PetscFunctionReturn(0); 2567a8054027SBarry Smith } 2568a8054027SBarry Smith 2569a8054027SBarry Smith #undef __FUNCT__ 2570e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2571e35cf81dSBarry Smith /*@ 2572e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2573e35cf81dSBarry Smith often the preconditioner is rebuilt. 2574e35cf81dSBarry Smith 25753f9fe445SBarry Smith Logically Collective on SNES 2576e35cf81dSBarry Smith 2577e35cf81dSBarry Smith Input Parameters: 2578e35cf81dSBarry Smith + snes - the SNES context 2579e35cf81dSBarry 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 2580fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2581e35cf81dSBarry Smith 2582e35cf81dSBarry Smith Options Database Keys: 2583e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2584e35cf81dSBarry Smith 2585e35cf81dSBarry Smith Notes: 2586e35cf81dSBarry Smith The default is 1 2587e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2588fe3ffe1eSBarry 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 2589fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2590e35cf81dSBarry Smith 2591e35cf81dSBarry Smith Level: intermediate 2592e35cf81dSBarry Smith 2593e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2594e35cf81dSBarry Smith 2595e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2596e35cf81dSBarry Smith 2597e35cf81dSBarry Smith @*/ 25987087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2599e35cf81dSBarry Smith { 2600e35cf81dSBarry Smith PetscFunctionBegin; 26010700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2602e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2603e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2604c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2605e35cf81dSBarry Smith snes->lagjacobian = lag; 2606e35cf81dSBarry Smith PetscFunctionReturn(0); 2607e35cf81dSBarry Smith } 2608e35cf81dSBarry Smith 2609e35cf81dSBarry Smith #undef __FUNCT__ 2610e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2611e35cf81dSBarry Smith /*@ 2612e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2613e35cf81dSBarry Smith 26143f9fe445SBarry Smith Not Collective 2615e35cf81dSBarry Smith 2616e35cf81dSBarry Smith Input Parameter: 2617e35cf81dSBarry Smith . snes - the SNES context 2618e35cf81dSBarry Smith 2619e35cf81dSBarry Smith Output Parameter: 2620e35cf81dSBarry 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 2621e35cf81dSBarry Smith the Jacobian is built etc. 2622e35cf81dSBarry Smith 2623e35cf81dSBarry Smith Options Database Keys: 2624e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2625e35cf81dSBarry Smith 2626e35cf81dSBarry Smith Notes: 2627e35cf81dSBarry Smith The default is 1 2628e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2629e35cf81dSBarry Smith 2630e35cf81dSBarry Smith Level: intermediate 2631e35cf81dSBarry Smith 2632e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2633e35cf81dSBarry Smith 2634e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2635e35cf81dSBarry Smith 2636e35cf81dSBarry Smith @*/ 26377087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2638e35cf81dSBarry Smith { 2639e35cf81dSBarry Smith PetscFunctionBegin; 26400700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2641e35cf81dSBarry Smith *lag = snes->lagjacobian; 2642e35cf81dSBarry Smith PetscFunctionReturn(0); 2643e35cf81dSBarry Smith } 2644e35cf81dSBarry Smith 2645e35cf81dSBarry Smith #undef __FUNCT__ 26464a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 26479b94acceSBarry Smith /*@ 2648d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 26499b94acceSBarry Smith 26503f9fe445SBarry Smith Logically Collective on SNES 2651c7afd0dbSLois Curfman McInnes 26529b94acceSBarry Smith Input Parameters: 2653c7afd0dbSLois Curfman McInnes + snes - the SNES context 265470441072SBarry Smith . abstol - absolute convergence tolerance 265533174efeSLois Curfman McInnes . rtol - relative convergence tolerance 265633174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 265733174efeSLois Curfman McInnes of the change in the solution between steps 265833174efeSLois Curfman McInnes . maxit - maximum number of iterations 2659c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2660fee21e36SBarry Smith 266133174efeSLois Curfman McInnes Options Database Keys: 266270441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2663c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2664c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2665c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2666c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 26679b94acceSBarry Smith 2668d7a720efSLois Curfman McInnes Notes: 26699b94acceSBarry Smith The default maximum number of iterations is 50. 26709b94acceSBarry Smith The default maximum number of function evaluations is 1000. 26719b94acceSBarry Smith 267236851e7fSLois Curfman McInnes Level: intermediate 267336851e7fSLois Curfman McInnes 267433174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 26759b94acceSBarry Smith 26762492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 26779b94acceSBarry Smith @*/ 26787087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 26799b94acceSBarry Smith { 26803a40ed3dSBarry Smith PetscFunctionBegin; 26810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2682c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2683c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2684c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2685c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2686c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2687c5eb9154SBarry Smith 2688ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2689ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2690ab54825eSJed Brown snes->abstol = abstol; 2691ab54825eSJed Brown } 2692ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2693ab54825eSJed 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); 2694ab54825eSJed Brown snes->rtol = rtol; 2695ab54825eSJed Brown } 2696ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2697ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2698c60f73f4SPeter Brune snes->stol = stol; 2699ab54825eSJed Brown } 2700ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2701ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2702ab54825eSJed Brown snes->max_its = maxit; 2703ab54825eSJed Brown } 2704ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2705ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2706ab54825eSJed Brown snes->max_funcs = maxf; 2707ab54825eSJed Brown } 270888976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 27093a40ed3dSBarry Smith PetscFunctionReturn(0); 27109b94acceSBarry Smith } 27119b94acceSBarry Smith 27124a2ae208SSatish Balay #undef __FUNCT__ 27134a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 27149b94acceSBarry Smith /*@ 271533174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 271633174efeSLois Curfman McInnes 2717c7afd0dbSLois Curfman McInnes Not Collective 2718c7afd0dbSLois Curfman McInnes 271933174efeSLois Curfman McInnes Input Parameters: 2720c7afd0dbSLois Curfman McInnes + snes - the SNES context 272185385478SLisandro Dalcin . atol - absolute convergence tolerance 272233174efeSLois Curfman McInnes . rtol - relative convergence tolerance 272333174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 272433174efeSLois Curfman McInnes of the change in the solution between steps 272533174efeSLois Curfman McInnes . maxit - maximum number of iterations 2726c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2727fee21e36SBarry Smith 272833174efeSLois Curfman McInnes Notes: 272933174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 273033174efeSLois Curfman McInnes 273136851e7fSLois Curfman McInnes Level: intermediate 273236851e7fSLois Curfman McInnes 273333174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 273433174efeSLois Curfman McInnes 273533174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 273633174efeSLois Curfman McInnes @*/ 27377087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 273833174efeSLois Curfman McInnes { 27393a40ed3dSBarry Smith PetscFunctionBegin; 27400700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 274185385478SLisandro Dalcin if (atol) *atol = snes->abstol; 274233174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 2743c60f73f4SPeter Brune if (stol) *stol = snes->stol; 274433174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 274533174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 27463a40ed3dSBarry Smith PetscFunctionReturn(0); 274733174efeSLois Curfman McInnes } 274833174efeSLois Curfman McInnes 27494a2ae208SSatish Balay #undef __FUNCT__ 27504a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 275133174efeSLois Curfman McInnes /*@ 27529b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 27539b94acceSBarry Smith 27543f9fe445SBarry Smith Logically Collective on SNES 2755fee21e36SBarry Smith 2756c7afd0dbSLois Curfman McInnes Input Parameters: 2757c7afd0dbSLois Curfman McInnes + snes - the SNES context 2758c7afd0dbSLois Curfman McInnes - tol - tolerance 2759c7afd0dbSLois Curfman McInnes 27609b94acceSBarry Smith Options Database Key: 2761c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 27629b94acceSBarry Smith 276336851e7fSLois Curfman McInnes Level: intermediate 276436851e7fSLois Curfman McInnes 27659b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 27669b94acceSBarry Smith 27672492ecdbSBarry Smith .seealso: SNESSetTolerances() 27689b94acceSBarry Smith @*/ 27697087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 27709b94acceSBarry Smith { 27713a40ed3dSBarry Smith PetscFunctionBegin; 27720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2773c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 27749b94acceSBarry Smith snes->deltatol = tol; 27753a40ed3dSBarry Smith PetscFunctionReturn(0); 27769b94acceSBarry Smith } 27779b94acceSBarry Smith 2778df9fa365SBarry Smith /* 2779df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2780df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2781df9fa365SBarry Smith macros instead of functions 2782df9fa365SBarry Smith */ 27834a2ae208SSatish Balay #undef __FUNCT__ 2784a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 27857087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2786ce1608b8SBarry Smith { 2787dfbe8321SBarry Smith PetscErrorCode ierr; 2788ce1608b8SBarry Smith 2789ce1608b8SBarry Smith PetscFunctionBegin; 27900700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2791a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2792ce1608b8SBarry Smith PetscFunctionReturn(0); 2793ce1608b8SBarry Smith } 2794ce1608b8SBarry Smith 27954a2ae208SSatish Balay #undef __FUNCT__ 2796a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 27977087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2798df9fa365SBarry Smith { 2799dfbe8321SBarry Smith PetscErrorCode ierr; 2800df9fa365SBarry Smith 2801df9fa365SBarry Smith PetscFunctionBegin; 2802a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2803df9fa365SBarry Smith PetscFunctionReturn(0); 2804df9fa365SBarry Smith } 2805df9fa365SBarry Smith 28064a2ae208SSatish Balay #undef __FUNCT__ 2807a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 28086bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2809df9fa365SBarry Smith { 2810dfbe8321SBarry Smith PetscErrorCode ierr; 2811df9fa365SBarry Smith 2812df9fa365SBarry Smith PetscFunctionBegin; 2813a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2814df9fa365SBarry Smith PetscFunctionReturn(0); 2815df9fa365SBarry Smith } 2816df9fa365SBarry Smith 28177087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2818b271bb04SBarry Smith #undef __FUNCT__ 2819b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 28207087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2821b271bb04SBarry Smith { 2822b271bb04SBarry Smith PetscDrawLG lg; 2823b271bb04SBarry Smith PetscErrorCode ierr; 2824b271bb04SBarry Smith PetscReal x,y,per; 2825b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2826b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2827b271bb04SBarry Smith PetscDraw draw; 2828b271bb04SBarry Smith PetscFunctionBegin; 2829b271bb04SBarry Smith if (!monctx) { 2830b271bb04SBarry Smith MPI_Comm comm; 2831b271bb04SBarry Smith 2832b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2833b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2834b271bb04SBarry Smith } 2835b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2836b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2837b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2838b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2839b271bb04SBarry Smith x = (PetscReal) n; 2840b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2841b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2842b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2843b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2844b271bb04SBarry Smith } 2845b271bb04SBarry Smith 2846b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2847b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2848b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2849b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2850b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2851b271bb04SBarry Smith x = (PetscReal) n; 2852b271bb04SBarry Smith y = 100.0*per; 2853b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2854b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2855b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2856b271bb04SBarry Smith } 2857b271bb04SBarry Smith 2858b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2859b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2860b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2861b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2862b271bb04SBarry Smith x = (PetscReal) n; 2863b271bb04SBarry Smith y = (prev - rnorm)/prev; 2864b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2865b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2866b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2867b271bb04SBarry Smith } 2868b271bb04SBarry Smith 2869b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2870b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2871b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2872b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2873b271bb04SBarry Smith x = (PetscReal) n; 2874b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2875b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2876b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2877b271bb04SBarry Smith } 2878b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2879b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2880b271bb04SBarry Smith } 2881b271bb04SBarry Smith prev = rnorm; 2882b271bb04SBarry Smith PetscFunctionReturn(0); 2883b271bb04SBarry Smith } 2884b271bb04SBarry Smith 2885b271bb04SBarry Smith #undef __FUNCT__ 2886b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 28877087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2888b271bb04SBarry Smith { 2889b271bb04SBarry Smith PetscErrorCode ierr; 2890b271bb04SBarry Smith 2891b271bb04SBarry Smith PetscFunctionBegin; 2892b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2893b271bb04SBarry Smith PetscFunctionReturn(0); 2894b271bb04SBarry Smith } 2895b271bb04SBarry Smith 2896b271bb04SBarry Smith #undef __FUNCT__ 2897b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 28986bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2899b271bb04SBarry Smith { 2900b271bb04SBarry Smith PetscErrorCode ierr; 2901b271bb04SBarry Smith 2902b271bb04SBarry Smith PetscFunctionBegin; 2903b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2904b271bb04SBarry Smith PetscFunctionReturn(0); 2905b271bb04SBarry Smith } 2906b271bb04SBarry Smith 29077a03ce2fSLisandro Dalcin #undef __FUNCT__ 29087a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 2909228d79bcSJed Brown /*@ 2910228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 2911228d79bcSJed Brown 2912228d79bcSJed Brown Collective on SNES 2913228d79bcSJed Brown 2914228d79bcSJed Brown Input Parameters: 2915228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 2916228d79bcSJed Brown . iter - iteration number 2917228d79bcSJed Brown - rnorm - relative norm of the residual 2918228d79bcSJed Brown 2919228d79bcSJed Brown Notes: 2920228d79bcSJed Brown This routine is called by the SNES implementations. 2921228d79bcSJed Brown It does not typically need to be called by the user. 2922228d79bcSJed Brown 2923228d79bcSJed Brown Level: developer 2924228d79bcSJed Brown 2925228d79bcSJed Brown .seealso: SNESMonitorSet() 2926228d79bcSJed Brown @*/ 29277a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 29287a03ce2fSLisandro Dalcin { 29297a03ce2fSLisandro Dalcin PetscErrorCode ierr; 29307a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 29317a03ce2fSLisandro Dalcin 29327a03ce2fSLisandro Dalcin PetscFunctionBegin; 29337a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 29347a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 29357a03ce2fSLisandro Dalcin } 29367a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 29377a03ce2fSLisandro Dalcin } 29387a03ce2fSLisandro Dalcin 29399b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 29409b94acceSBarry Smith 29414a2ae208SSatish Balay #undef __FUNCT__ 2942a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 29439b94acceSBarry Smith /*@C 2944a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 29459b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 29469b94acceSBarry Smith progress. 29479b94acceSBarry Smith 29483f9fe445SBarry Smith Logically Collective on SNES 2949fee21e36SBarry Smith 2950c7afd0dbSLois Curfman McInnes Input Parameters: 2951c7afd0dbSLois Curfman McInnes + snes - the SNES context 2952c7afd0dbSLois Curfman McInnes . func - monitoring routine 2953b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 2954e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 2955b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 2956b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 29579b94acceSBarry Smith 2958c7afd0dbSLois Curfman McInnes Calling sequence of func: 2959a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2960c7afd0dbSLois Curfman McInnes 2961c7afd0dbSLois Curfman McInnes + snes - the SNES context 2962c7afd0dbSLois Curfman McInnes . its - iteration number 2963c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 296440a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 29659b94acceSBarry Smith 29669665c990SLois Curfman McInnes Options Database Keys: 2967a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 2968a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 2969a6570f20SBarry Smith uses SNESMonitorLGCreate() 2970cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 2971c7afd0dbSLois Curfman McInnes been hardwired into a code by 2972a6570f20SBarry Smith calls to SNESMonitorSet(), but 2973c7afd0dbSLois Curfman McInnes does not cancel those set via 2974c7afd0dbSLois Curfman McInnes the options database. 29759665c990SLois Curfman McInnes 2976639f9d9dSBarry Smith Notes: 29776bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 2978a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 29796bc08f3fSLois Curfman McInnes order in which they were set. 2980639f9d9dSBarry Smith 2981025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 2982025f1a04SBarry Smith 298336851e7fSLois Curfman McInnes Level: intermediate 298436851e7fSLois Curfman McInnes 29859b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 29869b94acceSBarry Smith 2987a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 29889b94acceSBarry Smith @*/ 2989c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 29909b94acceSBarry Smith { 2991b90d0a6eSBarry Smith PetscInt i; 2992649052a6SBarry Smith PetscErrorCode ierr; 2993b90d0a6eSBarry Smith 29943a40ed3dSBarry Smith PetscFunctionBegin; 29950700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 299617186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2997b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 2998649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 2999649052a6SBarry Smith if (monitordestroy) { 3000c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 3001649052a6SBarry Smith } 3002b90d0a6eSBarry Smith PetscFunctionReturn(0); 3003b90d0a6eSBarry Smith } 3004b90d0a6eSBarry Smith } 3005b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 3006b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 3007639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 30083a40ed3dSBarry Smith PetscFunctionReturn(0); 30099b94acceSBarry Smith } 30109b94acceSBarry Smith 30114a2ae208SSatish Balay #undef __FUNCT__ 3012a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 30135cd90555SBarry Smith /*@C 3014a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 30155cd90555SBarry Smith 30163f9fe445SBarry Smith Logically Collective on SNES 3017c7afd0dbSLois Curfman McInnes 30185cd90555SBarry Smith Input Parameters: 30195cd90555SBarry Smith . snes - the SNES context 30205cd90555SBarry Smith 30211a480d89SAdministrator Options Database Key: 3022a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 3023a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 3024c7afd0dbSLois Curfman McInnes set via the options database 30255cd90555SBarry Smith 30265cd90555SBarry Smith Notes: 30275cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 30285cd90555SBarry Smith 302936851e7fSLois Curfman McInnes Level: intermediate 303036851e7fSLois Curfman McInnes 30315cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 30325cd90555SBarry Smith 3033a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 30345cd90555SBarry Smith @*/ 30357087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 30365cd90555SBarry Smith { 3037d952e501SBarry Smith PetscErrorCode ierr; 3038d952e501SBarry Smith PetscInt i; 3039d952e501SBarry Smith 30405cd90555SBarry Smith PetscFunctionBegin; 30410700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3042d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 3043d952e501SBarry Smith if (snes->monitordestroy[i]) { 30443c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 3045d952e501SBarry Smith } 3046d952e501SBarry Smith } 30475cd90555SBarry Smith snes->numbermonitors = 0; 30485cd90555SBarry Smith PetscFunctionReturn(0); 30495cd90555SBarry Smith } 30505cd90555SBarry Smith 30514a2ae208SSatish Balay #undef __FUNCT__ 30524a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 30539b94acceSBarry Smith /*@C 30549b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 30559b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 30569b94acceSBarry Smith 30573f9fe445SBarry Smith Logically Collective on SNES 3058fee21e36SBarry Smith 3059c7afd0dbSLois Curfman McInnes Input Parameters: 3060c7afd0dbSLois Curfman McInnes + snes - the SNES context 3061c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 30627f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 30637f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 30649b94acceSBarry Smith 3065c7afd0dbSLois Curfman McInnes Calling sequence of func: 306606ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 3067c7afd0dbSLois Curfman McInnes 3068c7afd0dbSLois Curfman McInnes + snes - the SNES context 306906ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 3070c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 3071184914b5SBarry Smith . reason - reason for convergence/divergence 3072c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 30734b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 30744b27c08aSLois Curfman McInnes - f - 2-norm of function 30759b94acceSBarry Smith 307636851e7fSLois Curfman McInnes Level: advanced 307736851e7fSLois Curfman McInnes 30789b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 30799b94acceSBarry Smith 308085385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 30819b94acceSBarry Smith @*/ 30827087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 30839b94acceSBarry Smith { 30847f7931b9SBarry Smith PetscErrorCode ierr; 30857f7931b9SBarry Smith 30863a40ed3dSBarry Smith PetscFunctionBegin; 30870700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 308885385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 30897f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 30907f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 30917f7931b9SBarry Smith } 309285385478SLisandro Dalcin snes->ops->converged = func; 30937f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 309485385478SLisandro Dalcin snes->cnvP = cctx; 30953a40ed3dSBarry Smith PetscFunctionReturn(0); 30969b94acceSBarry Smith } 30979b94acceSBarry Smith 30984a2ae208SSatish Balay #undef __FUNCT__ 30994a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 310052baeb72SSatish Balay /*@ 3101184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 3102184914b5SBarry Smith 3103184914b5SBarry Smith Not Collective 3104184914b5SBarry Smith 3105184914b5SBarry Smith Input Parameter: 3106184914b5SBarry Smith . snes - the SNES context 3107184914b5SBarry Smith 3108184914b5SBarry Smith Output Parameter: 31094d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 3110184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 3111184914b5SBarry Smith 3112184914b5SBarry Smith Level: intermediate 3113184914b5SBarry Smith 3114184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 3115184914b5SBarry Smith 3116184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 3117184914b5SBarry Smith 311885385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 3119184914b5SBarry Smith @*/ 31207087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 3121184914b5SBarry Smith { 3122184914b5SBarry Smith PetscFunctionBegin; 31230700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31244482741eSBarry Smith PetscValidPointer(reason,2); 3125184914b5SBarry Smith *reason = snes->reason; 3126184914b5SBarry Smith PetscFunctionReturn(0); 3127184914b5SBarry Smith } 3128184914b5SBarry Smith 31294a2ae208SSatish Balay #undef __FUNCT__ 31304a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 3131c9005455SLois Curfman McInnes /*@ 3132c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 3133c9005455SLois Curfman McInnes 31343f9fe445SBarry Smith Logically Collective on SNES 3135fee21e36SBarry Smith 3136c7afd0dbSLois Curfman McInnes Input Parameters: 3137c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 31388c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 3139cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 3140758f92a0SBarry Smith . na - size of a and its 314164731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 3142758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 3143c7afd0dbSLois Curfman McInnes 3144308dcc3eSBarry Smith Notes: 3145308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 3146308dcc3eSBarry Smith default array of length 10000 is allocated. 3147308dcc3eSBarry Smith 3148c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 3149c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 3150c9005455SLois Curfman McInnes during the section of code that is being timed. 3151c9005455SLois Curfman McInnes 315236851e7fSLois Curfman McInnes Level: intermediate 315336851e7fSLois Curfman McInnes 3154c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 3155758f92a0SBarry Smith 315608405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 3157758f92a0SBarry Smith 3158c9005455SLois Curfman McInnes @*/ 31597087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 3160c9005455SLois Curfman McInnes { 3161308dcc3eSBarry Smith PetscErrorCode ierr; 3162308dcc3eSBarry Smith 31633a40ed3dSBarry Smith PetscFunctionBegin; 31640700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31654482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 3166a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 3167308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 3168308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 3169308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 3170308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 3171308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 3172308dcc3eSBarry Smith } 3173c9005455SLois Curfman McInnes snes->conv_hist = a; 3174758f92a0SBarry Smith snes->conv_hist_its = its; 3175758f92a0SBarry Smith snes->conv_hist_max = na; 3176a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 3177758f92a0SBarry Smith snes->conv_hist_reset = reset; 3178758f92a0SBarry Smith PetscFunctionReturn(0); 3179758f92a0SBarry Smith } 3180758f92a0SBarry Smith 3181308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3182c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 3183c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 3184308dcc3eSBarry Smith EXTERN_C_BEGIN 3185308dcc3eSBarry Smith #undef __FUNCT__ 3186308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 3187308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3188308dcc3eSBarry Smith { 3189308dcc3eSBarry Smith mxArray *mat; 3190308dcc3eSBarry Smith PetscInt i; 3191308dcc3eSBarry Smith PetscReal *ar; 3192308dcc3eSBarry Smith 3193308dcc3eSBarry Smith PetscFunctionBegin; 3194308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3195308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3196308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 3197308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 3198308dcc3eSBarry Smith } 3199308dcc3eSBarry Smith PetscFunctionReturn(mat); 3200308dcc3eSBarry Smith } 3201308dcc3eSBarry Smith EXTERN_C_END 3202308dcc3eSBarry Smith #endif 3203308dcc3eSBarry Smith 3204308dcc3eSBarry Smith 32054a2ae208SSatish Balay #undef __FUNCT__ 32064a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 32070c4c9dddSBarry Smith /*@C 3208758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3209758f92a0SBarry Smith 32103f9fe445SBarry Smith Not Collective 3211758f92a0SBarry Smith 3212758f92a0SBarry Smith Input Parameter: 3213758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3214758f92a0SBarry Smith 3215758f92a0SBarry Smith Output Parameters: 3216758f92a0SBarry Smith . a - array to hold history 3217758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3218758f92a0SBarry Smith negative if not converged) for each solve. 3219758f92a0SBarry Smith - na - size of a and its 3220758f92a0SBarry Smith 3221758f92a0SBarry Smith Notes: 3222758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3223758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3224758f92a0SBarry Smith 3225758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3226758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3227758f92a0SBarry Smith during the section of code that is being timed. 3228758f92a0SBarry Smith 3229758f92a0SBarry Smith Level: intermediate 3230758f92a0SBarry Smith 3231758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3232758f92a0SBarry Smith 3233758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3234758f92a0SBarry Smith 3235758f92a0SBarry Smith @*/ 32367087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3237758f92a0SBarry Smith { 3238758f92a0SBarry Smith PetscFunctionBegin; 32390700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3240758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3241758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3242758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 32433a40ed3dSBarry Smith PetscFunctionReturn(0); 3244c9005455SLois Curfman McInnes } 3245c9005455SLois Curfman McInnes 3246e74ef692SMatthew Knepley #undef __FUNCT__ 3247e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 3248ac226902SBarry Smith /*@C 324976b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3250eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 32517e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 325276b2cf59SMatthew Knepley 32533f9fe445SBarry Smith Logically Collective on SNES 325476b2cf59SMatthew Knepley 325576b2cf59SMatthew Knepley Input Parameters: 325676b2cf59SMatthew Knepley . snes - The nonlinear solver context 325776b2cf59SMatthew Knepley . func - The function 325876b2cf59SMatthew Knepley 325976b2cf59SMatthew Knepley Calling sequence of func: 3260b5d30489SBarry Smith . func (SNES snes, PetscInt step); 326176b2cf59SMatthew Knepley 326276b2cf59SMatthew Knepley . step - The current step of the iteration 326376b2cf59SMatthew Knepley 3264fe97e370SBarry Smith Level: advanced 3265fe97e370SBarry Smith 3266fe97e370SBarry 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() 3267fe97e370SBarry Smith This is not used by most users. 326876b2cf59SMatthew Knepley 326976b2cf59SMatthew Knepley .keywords: SNES, update 3270b5d30489SBarry Smith 327185385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 327276b2cf59SMatthew Knepley @*/ 32737087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 327476b2cf59SMatthew Knepley { 327576b2cf59SMatthew Knepley PetscFunctionBegin; 32760700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3277e7788613SBarry Smith snes->ops->update = func; 327876b2cf59SMatthew Knepley PetscFunctionReturn(0); 327976b2cf59SMatthew Knepley } 328076b2cf59SMatthew Knepley 3281e74ef692SMatthew Knepley #undef __FUNCT__ 3282e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 328376b2cf59SMatthew Knepley /*@ 328476b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 328576b2cf59SMatthew Knepley 328676b2cf59SMatthew Knepley Not collective 328776b2cf59SMatthew Knepley 328876b2cf59SMatthew Knepley Input Parameters: 328976b2cf59SMatthew Knepley . snes - The nonlinear solver context 329076b2cf59SMatthew Knepley . step - The current step of the iteration 329176b2cf59SMatthew Knepley 3292205452f4SMatthew Knepley Level: intermediate 3293205452f4SMatthew Knepley 329476b2cf59SMatthew Knepley .keywords: SNES, update 3295a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 329676b2cf59SMatthew Knepley @*/ 32977087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 329876b2cf59SMatthew Knepley { 329976b2cf59SMatthew Knepley PetscFunctionBegin; 330076b2cf59SMatthew Knepley PetscFunctionReturn(0); 330176b2cf59SMatthew Knepley } 330276b2cf59SMatthew Knepley 33034a2ae208SSatish Balay #undef __FUNCT__ 33044a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 33059b94acceSBarry Smith /* 33069b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 33079b94acceSBarry Smith positive parameter delta. 33089b94acceSBarry Smith 33099b94acceSBarry Smith Input Parameters: 3310c7afd0dbSLois Curfman McInnes + snes - the SNES context 33119b94acceSBarry Smith . y - approximate solution of linear system 33129b94acceSBarry Smith . fnorm - 2-norm of current function 3313c7afd0dbSLois Curfman McInnes - delta - trust region size 33149b94acceSBarry Smith 33159b94acceSBarry Smith Output Parameters: 3316c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 33179b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 33189b94acceSBarry Smith region, and exceeds zero otherwise. 3319c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 33209b94acceSBarry Smith 33219b94acceSBarry Smith Note: 33224b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 33239b94acceSBarry Smith is set to be the maximum allowable step size. 33249b94acceSBarry Smith 33259b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 33269b94acceSBarry Smith */ 3327dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 33289b94acceSBarry Smith { 3329064f8208SBarry Smith PetscReal nrm; 3330ea709b57SSatish Balay PetscScalar cnorm; 3331dfbe8321SBarry Smith PetscErrorCode ierr; 33323a40ed3dSBarry Smith 33333a40ed3dSBarry Smith PetscFunctionBegin; 33340700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 33350700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3336c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3337184914b5SBarry Smith 3338064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3339064f8208SBarry Smith if (nrm > *delta) { 3340064f8208SBarry Smith nrm = *delta/nrm; 3341064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3342064f8208SBarry Smith cnorm = nrm; 33432dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 33449b94acceSBarry Smith *ynorm = *delta; 33459b94acceSBarry Smith } else { 33469b94acceSBarry Smith *gpnorm = 0.0; 3347064f8208SBarry Smith *ynorm = nrm; 33489b94acceSBarry Smith } 33493a40ed3dSBarry Smith PetscFunctionReturn(0); 33509b94acceSBarry Smith } 33519b94acceSBarry Smith 33524a2ae208SSatish Balay #undef __FUNCT__ 33534a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 33546ce558aeSBarry Smith /*@C 3355f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3356f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 33579b94acceSBarry Smith 3358c7afd0dbSLois Curfman McInnes Collective on SNES 3359c7afd0dbSLois Curfman McInnes 3360b2002411SLois Curfman McInnes Input Parameters: 3361c7afd0dbSLois Curfman McInnes + snes - the SNES context 33623cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 336385385478SLisandro Dalcin - x - the solution vector. 33649b94acceSBarry Smith 3365b2002411SLois Curfman McInnes Notes: 33668ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 33678ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 33688ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 33698ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 33708ddd3da0SLois Curfman McInnes 337136851e7fSLois Curfman McInnes Level: beginner 337236851e7fSLois Curfman McInnes 33739b94acceSBarry Smith .keywords: SNES, nonlinear, solve 33749b94acceSBarry Smith 3375c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 33769b94acceSBarry Smith @*/ 33777087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 33789b94acceSBarry Smith { 3379dfbe8321SBarry Smith PetscErrorCode ierr; 3380ace3abfcSBarry Smith PetscBool flg; 3381eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 3382eabae89aSBarry Smith PetscViewer viewer; 3383efd51863SBarry Smith PetscInt grid; 3384a69afd8bSBarry Smith Vec xcreated = PETSC_NULL; 3385caa4e7f2SJed Brown DM dm; 3386052efed2SBarry Smith 33873a40ed3dSBarry Smith PetscFunctionBegin; 33880700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3389a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3390a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 33910700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 339285385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 339385385478SLisandro Dalcin 3394caa4e7f2SJed Brown if (!x) { 3395caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3396caa4e7f2SJed Brown ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 3397a69afd8bSBarry Smith x = xcreated; 3398a69afd8bSBarry Smith } 3399a69afd8bSBarry Smith 3400a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3401efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3402efd51863SBarry Smith 340385385478SLisandro Dalcin /* set solution vector */ 3404efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 34056bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 340685385478SLisandro Dalcin snes->vec_sol = x; 3407caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3408caa4e7f2SJed Brown 3409caa4e7f2SJed Brown /* set affine vector if provided */ 341085385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 34116bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 341285385478SLisandro Dalcin snes->vec_rhs = b; 341385385478SLisandro Dalcin 341470e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 34153f149594SLisandro Dalcin 34167eee914bSBarry Smith if (!grid) { 34177eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3418d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3419dd568438SSatish Balay } else if (snes->dm) { 3420dd568438SSatish Balay PetscBool ig; 3421dd568438SSatish Balay ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr); 3422dd568438SSatish Balay if (ig) { 34237eee914bSBarry Smith ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr); 34247eee914bSBarry Smith } 3425d25893d9SBarry Smith } 3426dd568438SSatish Balay } 3427d25893d9SBarry Smith 3428abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 342950ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3430d5e45103SBarry Smith 34313f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 34324936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 343385385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 34344936397dSBarry Smith if (snes->domainerror){ 34354936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 34364936397dSBarry Smith snes->domainerror = PETSC_FALSE; 34374936397dSBarry Smith } 343817186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 34393f149594SLisandro Dalcin 34407adad957SLisandro Dalcin ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 3441eabae89aSBarry Smith if (flg && !PetscPreLoadingOn) { 34427adad957SLisandro Dalcin ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 3443eabae89aSBarry Smith ierr = SNESView(snes,viewer);CHKERRQ(ierr); 34446bf464f9SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3445eabae89aSBarry Smith } 3446eabae89aSBarry Smith 344790d69ab7SBarry Smith flg = PETSC_FALSE; 3448acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3449da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 34505968eb51SBarry Smith if (snes->printreason) { 3451a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 34525968eb51SBarry Smith if (snes->reason > 0) { 3453c7e7b494SJed 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); 34545968eb51SBarry Smith } else { 3455c7e7b494SJed 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); 34565968eb51SBarry Smith } 3457a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 34585968eb51SBarry Smith } 34595968eb51SBarry Smith 34608501fc72SJed Brown flg = PETSC_FALSE; 34618501fc72SJed Brown ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 34628501fc72SJed Brown if (flg) { 34638501fc72SJed Brown PetscViewer viewer; 34648501fc72SJed Brown ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 34658501fc72SJed Brown ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 34668501fc72SJed Brown ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 34678501fc72SJed Brown ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 34688501fc72SJed Brown ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 34698501fc72SJed Brown } 34708501fc72SJed Brown 3471e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3472efd51863SBarry Smith if (grid < snes->gridsequence) { 3473efd51863SBarry Smith DM fine; 3474efd51863SBarry Smith Vec xnew; 3475efd51863SBarry Smith Mat interp; 3476efd51863SBarry Smith 3477efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3478c5c77316SJed Brown if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 3479e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3480efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3481efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3482c833c3b5SJed Brown ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr); 3483efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3484efd51863SBarry Smith x = xnew; 3485efd51863SBarry Smith 3486efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3487efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3488efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3489a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3490efd51863SBarry Smith } 3491efd51863SBarry Smith } 3492a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 34933a40ed3dSBarry Smith PetscFunctionReturn(0); 34949b94acceSBarry Smith } 34959b94acceSBarry Smith 34969b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 34979b94acceSBarry Smith 34984a2ae208SSatish Balay #undef __FUNCT__ 34994a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 350082bf6240SBarry Smith /*@C 35014b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 35029b94acceSBarry Smith 3503fee21e36SBarry Smith Collective on SNES 3504fee21e36SBarry Smith 3505c7afd0dbSLois Curfman McInnes Input Parameters: 3506c7afd0dbSLois Curfman McInnes + snes - the SNES context 3507454a90a3SBarry Smith - type - a known method 3508c7afd0dbSLois Curfman McInnes 3509c7afd0dbSLois Curfman McInnes Options Database Key: 3510454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3511c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3512ae12b187SLois Curfman McInnes 35139b94acceSBarry Smith Notes: 3514e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 35154b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3516c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 35174b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3518c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 35199b94acceSBarry Smith 3520ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3521ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3522ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3523ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3524ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3525ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3526ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3527ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3528ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3529b0a32e0cSBarry Smith appropriate method. 353036851e7fSLois Curfman McInnes 353136851e7fSLois Curfman McInnes Level: intermediate 3532a703fe33SLois Curfman McInnes 3533454a90a3SBarry Smith .keywords: SNES, set, type 3534435da068SBarry Smith 3535435da068SBarry Smith .seealso: SNESType, SNESCreate() 3536435da068SBarry Smith 35379b94acceSBarry Smith @*/ 35387087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 35399b94acceSBarry Smith { 3540dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3541ace3abfcSBarry Smith PetscBool match; 35423a40ed3dSBarry Smith 35433a40ed3dSBarry Smith PetscFunctionBegin; 35440700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35454482741eSBarry Smith PetscValidCharPointer(type,2); 354682bf6240SBarry Smith 3547251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 35480f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 354992ff6ae8SBarry Smith 35504b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3551e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 355275396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 3553b5c23020SJed Brown if (snes->ops->destroy) { 3554b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 3555b5c23020SJed Brown snes->ops->destroy = PETSC_NULL; 3556b5c23020SJed Brown } 355775396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 355875396ef9SLisandro Dalcin snes->ops->setup = 0; 355975396ef9SLisandro Dalcin snes->ops->solve = 0; 356075396ef9SLisandro Dalcin snes->ops->view = 0; 356175396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 356275396ef9SLisandro Dalcin snes->ops->destroy = 0; 356375396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 356475396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3565454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 356603bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 35679fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 35689fb22e1aSBarry Smith if (PetscAMSPublishAll) { 35699fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 35709fb22e1aSBarry Smith } 35719fb22e1aSBarry Smith #endif 35723a40ed3dSBarry Smith PetscFunctionReturn(0); 35739b94acceSBarry Smith } 35749b94acceSBarry Smith 3575a847f771SSatish Balay 35769b94acceSBarry Smith /* --------------------------------------------------------------------- */ 35774a2ae208SSatish Balay #undef __FUNCT__ 35784a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 357952baeb72SSatish Balay /*@ 35809b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3581f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 35829b94acceSBarry Smith 3583fee21e36SBarry Smith Not Collective 3584fee21e36SBarry Smith 358536851e7fSLois Curfman McInnes Level: advanced 358636851e7fSLois Curfman McInnes 35879b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 35889b94acceSBarry Smith 35899b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 35909b94acceSBarry Smith @*/ 35917087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 35929b94acceSBarry Smith { 3593dfbe8321SBarry Smith PetscErrorCode ierr; 359482bf6240SBarry Smith 35953a40ed3dSBarry Smith PetscFunctionBegin; 35961441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 35974c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 35983a40ed3dSBarry Smith PetscFunctionReturn(0); 35999b94acceSBarry Smith } 36009b94acceSBarry Smith 36014a2ae208SSatish Balay #undef __FUNCT__ 36024a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 36039b94acceSBarry Smith /*@C 36049a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 36059b94acceSBarry Smith 3606c7afd0dbSLois Curfman McInnes Not Collective 3607c7afd0dbSLois Curfman McInnes 36089b94acceSBarry Smith Input Parameter: 36094b0e389bSBarry Smith . snes - nonlinear solver context 36109b94acceSBarry Smith 36119b94acceSBarry Smith Output Parameter: 36123a7fca6bSBarry Smith . type - SNES method (a character string) 36139b94acceSBarry Smith 361436851e7fSLois Curfman McInnes Level: intermediate 361536851e7fSLois Curfman McInnes 3616454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 36179b94acceSBarry Smith @*/ 36187087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 36199b94acceSBarry Smith { 36203a40ed3dSBarry Smith PetscFunctionBegin; 36210700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36224482741eSBarry Smith PetscValidPointer(type,2); 36237adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 36243a40ed3dSBarry Smith PetscFunctionReturn(0); 36259b94acceSBarry Smith } 36269b94acceSBarry Smith 36274a2ae208SSatish Balay #undef __FUNCT__ 36284a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 362952baeb72SSatish Balay /*@ 36309b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3631c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 36329b94acceSBarry Smith 3633c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3634c7afd0dbSLois Curfman McInnes 36359b94acceSBarry Smith Input Parameter: 36369b94acceSBarry Smith . snes - the SNES context 36379b94acceSBarry Smith 36389b94acceSBarry Smith Output Parameter: 36399b94acceSBarry Smith . x - the solution 36409b94acceSBarry Smith 364170e92668SMatthew Knepley Level: intermediate 364236851e7fSLois Curfman McInnes 36439b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 36449b94acceSBarry Smith 364585385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 36469b94acceSBarry Smith @*/ 36477087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 36489b94acceSBarry Smith { 36493a40ed3dSBarry Smith PetscFunctionBegin; 36500700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36514482741eSBarry Smith PetscValidPointer(x,2); 365285385478SLisandro Dalcin *x = snes->vec_sol; 365370e92668SMatthew Knepley PetscFunctionReturn(0); 365470e92668SMatthew Knepley } 365570e92668SMatthew Knepley 365670e92668SMatthew Knepley #undef __FUNCT__ 36574a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 365852baeb72SSatish Balay /*@ 36599b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 36609b94acceSBarry Smith stored. 36619b94acceSBarry Smith 3662c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3663c7afd0dbSLois Curfman McInnes 36649b94acceSBarry Smith Input Parameter: 36659b94acceSBarry Smith . snes - the SNES context 36669b94acceSBarry Smith 36679b94acceSBarry Smith Output Parameter: 36689b94acceSBarry Smith . x - the solution update 36699b94acceSBarry Smith 367036851e7fSLois Curfman McInnes Level: advanced 367136851e7fSLois Curfman McInnes 36729b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 36739b94acceSBarry Smith 367485385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 36759b94acceSBarry Smith @*/ 36767087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 36779b94acceSBarry Smith { 36783a40ed3dSBarry Smith PetscFunctionBegin; 36790700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36804482741eSBarry Smith PetscValidPointer(x,2); 368185385478SLisandro Dalcin *x = snes->vec_sol_update; 36823a40ed3dSBarry Smith PetscFunctionReturn(0); 36839b94acceSBarry Smith } 36849b94acceSBarry Smith 36854a2ae208SSatish Balay #undef __FUNCT__ 36864a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 36879b94acceSBarry Smith /*@C 36883638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 36899b94acceSBarry Smith 3690a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 3691c7afd0dbSLois Curfman McInnes 36929b94acceSBarry Smith Input Parameter: 36939b94acceSBarry Smith . snes - the SNES context 36949b94acceSBarry Smith 36959b94acceSBarry Smith Output Parameter: 36967bf4e008SBarry Smith + r - the function (or PETSC_NULL) 369770e92668SMatthew Knepley . func - the function (or PETSC_NULL) 369870e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 36999b94acceSBarry Smith 370036851e7fSLois Curfman McInnes Level: advanced 370136851e7fSLois Curfman McInnes 3702a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 37039b94acceSBarry Smith 37044b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 37059b94acceSBarry Smith @*/ 37067087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 37079b94acceSBarry Smith { 3708a63bb30eSJed Brown PetscErrorCode ierr; 37096cab3a1bSJed Brown DM dm; 3710a63bb30eSJed Brown 37113a40ed3dSBarry Smith PetscFunctionBegin; 37120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3713a63bb30eSJed Brown if (r) { 3714a63bb30eSJed Brown if (!snes->vec_func) { 3715a63bb30eSJed Brown if (snes->vec_rhs) { 3716a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 3717a63bb30eSJed Brown } else if (snes->vec_sol) { 3718a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 3719a63bb30eSJed Brown } else if (snes->dm) { 3720a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 3721a63bb30eSJed Brown } 3722a63bb30eSJed Brown } 3723a63bb30eSJed Brown *r = snes->vec_func; 3724a63bb30eSJed Brown } 37256cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 37266cab3a1bSJed Brown ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr); 37273a40ed3dSBarry Smith PetscFunctionReturn(0); 37289b94acceSBarry Smith } 37299b94acceSBarry Smith 3730c79ef259SPeter Brune /*@C 3731c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3732c79ef259SPeter Brune 3733c79ef259SPeter Brune Input Parameter: 3734c79ef259SPeter Brune . snes - the SNES context 3735c79ef259SPeter Brune 3736c79ef259SPeter Brune Output Parameter: 3737c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3738c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3739c79ef259SPeter Brune 3740c79ef259SPeter Brune Level: advanced 3741c79ef259SPeter Brune 3742c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3743c79ef259SPeter Brune 3744c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3745c79ef259SPeter Brune @*/ 3746c79ef259SPeter Brune 37474a2ae208SSatish Balay #undef __FUNCT__ 3748646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3749646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3750646217ecSPeter Brune { 37516cab3a1bSJed Brown PetscErrorCode ierr; 37526cab3a1bSJed Brown DM dm; 37536cab3a1bSJed Brown 3754646217ecSPeter Brune PetscFunctionBegin; 3755646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37566cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 37576cab3a1bSJed Brown ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr); 3758646217ecSPeter Brune PetscFunctionReturn(0); 3759646217ecSPeter Brune } 3760646217ecSPeter Brune 37614a2ae208SSatish Balay #undef __FUNCT__ 37624a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 37633c7409f5SSatish Balay /*@C 37643c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3765d850072dSLois Curfman McInnes SNES options in the database. 37663c7409f5SSatish Balay 37673f9fe445SBarry Smith Logically Collective on SNES 3768fee21e36SBarry Smith 3769c7afd0dbSLois Curfman McInnes Input Parameter: 3770c7afd0dbSLois Curfman McInnes + snes - the SNES context 3771c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3772c7afd0dbSLois Curfman McInnes 3773d850072dSLois Curfman McInnes Notes: 3774a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3775c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3776d850072dSLois Curfman McInnes 377736851e7fSLois Curfman McInnes Level: advanced 377836851e7fSLois Curfman McInnes 37793c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3780a86d99e1SLois Curfman McInnes 3781a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 37823c7409f5SSatish Balay @*/ 37837087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 37843c7409f5SSatish Balay { 3785dfbe8321SBarry Smith PetscErrorCode ierr; 37863c7409f5SSatish Balay 37873a40ed3dSBarry Smith PetscFunctionBegin; 37880700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3789639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 37901cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 379194b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 37923a40ed3dSBarry Smith PetscFunctionReturn(0); 37933c7409f5SSatish Balay } 37943c7409f5SSatish Balay 37954a2ae208SSatish Balay #undef __FUNCT__ 37964a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 37973c7409f5SSatish Balay /*@C 3798f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3799d850072dSLois Curfman McInnes SNES options in the database. 38003c7409f5SSatish Balay 38013f9fe445SBarry Smith Logically Collective on SNES 3802fee21e36SBarry Smith 3803c7afd0dbSLois Curfman McInnes Input Parameters: 3804c7afd0dbSLois Curfman McInnes + snes - the SNES context 3805c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3806c7afd0dbSLois Curfman McInnes 3807d850072dSLois Curfman McInnes Notes: 3808a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3809c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3810d850072dSLois Curfman McInnes 381136851e7fSLois Curfman McInnes Level: advanced 381236851e7fSLois Curfman McInnes 38133c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3814a86d99e1SLois Curfman McInnes 3815a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 38163c7409f5SSatish Balay @*/ 38177087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 38183c7409f5SSatish Balay { 3819dfbe8321SBarry Smith PetscErrorCode ierr; 38203c7409f5SSatish Balay 38213a40ed3dSBarry Smith PetscFunctionBegin; 38220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3823639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 38241cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 382594b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 38263a40ed3dSBarry Smith PetscFunctionReturn(0); 38273c7409f5SSatish Balay } 38283c7409f5SSatish Balay 38294a2ae208SSatish Balay #undef __FUNCT__ 38304a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 38319ab63eb5SSatish Balay /*@C 38323c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 38333c7409f5SSatish Balay SNES options in the database. 38343c7409f5SSatish Balay 3835c7afd0dbSLois Curfman McInnes Not Collective 3836c7afd0dbSLois Curfman McInnes 38373c7409f5SSatish Balay Input Parameter: 38383c7409f5SSatish Balay . snes - the SNES context 38393c7409f5SSatish Balay 38403c7409f5SSatish Balay Output Parameter: 38413c7409f5SSatish Balay . prefix - pointer to the prefix string used 38423c7409f5SSatish Balay 38434ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 38449ab63eb5SSatish Balay sufficient length to hold the prefix. 38459ab63eb5SSatish Balay 384636851e7fSLois Curfman McInnes Level: advanced 384736851e7fSLois Curfman McInnes 38483c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 3849a86d99e1SLois Curfman McInnes 3850a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 38513c7409f5SSatish Balay @*/ 38527087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 38533c7409f5SSatish Balay { 3854dfbe8321SBarry Smith PetscErrorCode ierr; 38553c7409f5SSatish Balay 38563a40ed3dSBarry Smith PetscFunctionBegin; 38570700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3858639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 38593a40ed3dSBarry Smith PetscFunctionReturn(0); 38603c7409f5SSatish Balay } 38613c7409f5SSatish Balay 3862b2002411SLois Curfman McInnes 38634a2ae208SSatish Balay #undef __FUNCT__ 38644a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 38653cea93caSBarry Smith /*@C 38663cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 38673cea93caSBarry Smith 38687f6c08e0SMatthew Knepley Level: advanced 38693cea93caSBarry Smith @*/ 38707087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3871b2002411SLois Curfman McInnes { 3872e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3873dfbe8321SBarry Smith PetscErrorCode ierr; 3874b2002411SLois Curfman McInnes 3875b2002411SLois Curfman McInnes PetscFunctionBegin; 3876b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3877c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3878b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3879b2002411SLois Curfman McInnes } 3880da9b6338SBarry Smith 3881da9b6338SBarry Smith #undef __FUNCT__ 3882da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 38837087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3884da9b6338SBarry Smith { 3885dfbe8321SBarry Smith PetscErrorCode ierr; 388677431f27SBarry Smith PetscInt N,i,j; 3887da9b6338SBarry Smith Vec u,uh,fh; 3888da9b6338SBarry Smith PetscScalar value; 3889da9b6338SBarry Smith PetscReal norm; 3890da9b6338SBarry Smith 3891da9b6338SBarry Smith PetscFunctionBegin; 3892da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3893da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3894da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3895da9b6338SBarry Smith 3896da9b6338SBarry Smith /* currently only works for sequential */ 3897da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3898da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3899da9b6338SBarry Smith for (i=0; i<N; i++) { 3900da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 390177431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3902da9b6338SBarry Smith for (j=-10; j<11; j++) { 3903ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3904da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 39053ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3906da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 390777431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3908da9b6338SBarry Smith value = -value; 3909da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3910da9b6338SBarry Smith } 3911da9b6338SBarry Smith } 39126bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 39136bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 3914da9b6338SBarry Smith PetscFunctionReturn(0); 3915da9b6338SBarry Smith } 391671f87433Sdalcinl 391771f87433Sdalcinl #undef __FUNCT__ 3918fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 391971f87433Sdalcinl /*@ 3920fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 392171f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 392271f87433Sdalcinl Newton method. 392371f87433Sdalcinl 39243f9fe445SBarry Smith Logically Collective on SNES 392571f87433Sdalcinl 392671f87433Sdalcinl Input Parameters: 392771f87433Sdalcinl + snes - SNES context 392871f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 392971f87433Sdalcinl 393064ba62caSBarry Smith Options Database: 393164ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 393264ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 393364ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 393464ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 393564ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 393664ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 393764ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 393864ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 393964ba62caSBarry Smith 394071f87433Sdalcinl Notes: 394171f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 394271f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 394371f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 394471f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 394571f87433Sdalcinl solver. 394671f87433Sdalcinl 394771f87433Sdalcinl Level: advanced 394871f87433Sdalcinl 394971f87433Sdalcinl Reference: 395071f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 395171f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 395271f87433Sdalcinl 395371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 395471f87433Sdalcinl 3955fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 395671f87433Sdalcinl @*/ 39577087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 395871f87433Sdalcinl { 395971f87433Sdalcinl PetscFunctionBegin; 39600700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3961acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 396271f87433Sdalcinl snes->ksp_ewconv = flag; 396371f87433Sdalcinl PetscFunctionReturn(0); 396471f87433Sdalcinl } 396571f87433Sdalcinl 396671f87433Sdalcinl #undef __FUNCT__ 3967fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 396871f87433Sdalcinl /*@ 3969fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 397071f87433Sdalcinl for computing relative tolerance for linear solvers within an 397171f87433Sdalcinl inexact Newton method. 397271f87433Sdalcinl 397371f87433Sdalcinl Not Collective 397471f87433Sdalcinl 397571f87433Sdalcinl Input Parameter: 397671f87433Sdalcinl . snes - SNES context 397771f87433Sdalcinl 397871f87433Sdalcinl Output Parameter: 397971f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 398071f87433Sdalcinl 398171f87433Sdalcinl Notes: 398271f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 398371f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 398471f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 398571f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 398671f87433Sdalcinl solver. 398771f87433Sdalcinl 398871f87433Sdalcinl Level: advanced 398971f87433Sdalcinl 399071f87433Sdalcinl Reference: 399171f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 399271f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 399371f87433Sdalcinl 399471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 399571f87433Sdalcinl 3996fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 399771f87433Sdalcinl @*/ 39987087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 399971f87433Sdalcinl { 400071f87433Sdalcinl PetscFunctionBegin; 40010700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 400271f87433Sdalcinl PetscValidPointer(flag,2); 400371f87433Sdalcinl *flag = snes->ksp_ewconv; 400471f87433Sdalcinl PetscFunctionReturn(0); 400571f87433Sdalcinl } 400671f87433Sdalcinl 400771f87433Sdalcinl #undef __FUNCT__ 4008fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 400971f87433Sdalcinl /*@ 4010fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 401171f87433Sdalcinl convergence criteria for the linear solvers within an inexact 401271f87433Sdalcinl Newton method. 401371f87433Sdalcinl 40143f9fe445SBarry Smith Logically Collective on SNES 401571f87433Sdalcinl 401671f87433Sdalcinl Input Parameters: 401771f87433Sdalcinl + snes - SNES context 401871f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 401971f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 402071f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 402171f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 402271f87433Sdalcinl (0 <= gamma2 <= 1) 402371f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 402471f87433Sdalcinl . alpha2 - power for safeguard 402571f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 402671f87433Sdalcinl 402771f87433Sdalcinl Note: 402871f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 402971f87433Sdalcinl 403071f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 403171f87433Sdalcinl 403271f87433Sdalcinl Level: advanced 403371f87433Sdalcinl 403471f87433Sdalcinl Reference: 403571f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 403671f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 403771f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 403871f87433Sdalcinl 403971f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 404071f87433Sdalcinl 4041fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 404271f87433Sdalcinl @*/ 40437087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 404471f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 404571f87433Sdalcinl { 4046fa9f3622SBarry Smith SNESKSPEW *kctx; 404771f87433Sdalcinl PetscFunctionBegin; 40480700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4049fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4050e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 4051c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 4052c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 4053c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 4054c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 4055c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 4056c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 4057c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 405871f87433Sdalcinl 405971f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 406071f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 406171f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 406271f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 406371f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 406471f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 406571f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 406671f87433Sdalcinl 406771f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 4068e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 406971f87433Sdalcinl } 407071f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 4071e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 407271f87433Sdalcinl } 407371f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 4074e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 407571f87433Sdalcinl } 407671f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 4077e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 407871f87433Sdalcinl } 407971f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 4080e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 408171f87433Sdalcinl } 408271f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 4083e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 408471f87433Sdalcinl } 408571f87433Sdalcinl PetscFunctionReturn(0); 408671f87433Sdalcinl } 408771f87433Sdalcinl 408871f87433Sdalcinl #undef __FUNCT__ 4089fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 409071f87433Sdalcinl /*@ 4091fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 409271f87433Sdalcinl convergence criteria for the linear solvers within an inexact 409371f87433Sdalcinl Newton method. 409471f87433Sdalcinl 409571f87433Sdalcinl Not Collective 409671f87433Sdalcinl 409771f87433Sdalcinl Input Parameters: 409871f87433Sdalcinl snes - SNES context 409971f87433Sdalcinl 410071f87433Sdalcinl Output Parameters: 410171f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 410271f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 410371f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 410471f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 410571f87433Sdalcinl (0 <= gamma2 <= 1) 410671f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 410771f87433Sdalcinl . alpha2 - power for safeguard 410871f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 410971f87433Sdalcinl 411071f87433Sdalcinl Level: advanced 411171f87433Sdalcinl 411271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 411371f87433Sdalcinl 4114fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 411571f87433Sdalcinl @*/ 41167087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 411771f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 411871f87433Sdalcinl { 4119fa9f3622SBarry Smith SNESKSPEW *kctx; 412071f87433Sdalcinl PetscFunctionBegin; 41210700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4122fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4123e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 412471f87433Sdalcinl if(version) *version = kctx->version; 412571f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 412671f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 412771f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 412871f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 412971f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 413071f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 413171f87433Sdalcinl PetscFunctionReturn(0); 413271f87433Sdalcinl } 413371f87433Sdalcinl 413471f87433Sdalcinl #undef __FUNCT__ 4135fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 4136fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 413771f87433Sdalcinl { 413871f87433Sdalcinl PetscErrorCode ierr; 4139fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 414071f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 414171f87433Sdalcinl 414271f87433Sdalcinl PetscFunctionBegin; 4143e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 414471f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 414571f87433Sdalcinl rtol = kctx->rtol_0; 414671f87433Sdalcinl } else { 414771f87433Sdalcinl if (kctx->version == 1) { 414871f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 414971f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 415071f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 415171f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 415271f87433Sdalcinl } else if (kctx->version == 2) { 415371f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 415471f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 415571f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 415671f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 415771f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 415871f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 415971f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 416071f87433Sdalcinl stol = PetscMax(rtol,stol); 416171f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 416271f87433Sdalcinl /* safeguard: avoid oversolving */ 416371f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 416471f87433Sdalcinl stol = PetscMax(rtol,stol); 416571f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 4166e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 416771f87433Sdalcinl } 416871f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 416971f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 417071f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 417171f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 417271f87433Sdalcinl PetscFunctionReturn(0); 417371f87433Sdalcinl } 417471f87433Sdalcinl 417571f87433Sdalcinl #undef __FUNCT__ 4176fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 4177fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 417871f87433Sdalcinl { 417971f87433Sdalcinl PetscErrorCode ierr; 4180fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 418171f87433Sdalcinl PCSide pcside; 418271f87433Sdalcinl Vec lres; 418371f87433Sdalcinl 418471f87433Sdalcinl PetscFunctionBegin; 4185e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 418671f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 418771f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 418871f87433Sdalcinl if (kctx->version == 1) { 4189b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 419071f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 419171f87433Sdalcinl /* KSP residual is true linear residual */ 419271f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 419371f87433Sdalcinl } else { 419471f87433Sdalcinl /* KSP residual is preconditioned residual */ 419571f87433Sdalcinl /* compute true linear residual norm */ 419671f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 419771f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 419871f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 419971f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 42006bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 420171f87433Sdalcinl } 420271f87433Sdalcinl } 420371f87433Sdalcinl PetscFunctionReturn(0); 420471f87433Sdalcinl } 420571f87433Sdalcinl 420671f87433Sdalcinl #undef __FUNCT__ 420771f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 420871f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 420971f87433Sdalcinl { 421071f87433Sdalcinl PetscErrorCode ierr; 421171f87433Sdalcinl 421271f87433Sdalcinl PetscFunctionBegin; 4213fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 421471f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 4215fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 421671f87433Sdalcinl PetscFunctionReturn(0); 421771f87433Sdalcinl } 42186c699258SBarry Smith 42196c699258SBarry Smith #undef __FUNCT__ 42206c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 42216c699258SBarry Smith /*@ 42226c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 42236c699258SBarry Smith 42243f9fe445SBarry Smith Logically Collective on SNES 42256c699258SBarry Smith 42266c699258SBarry Smith Input Parameters: 42276c699258SBarry Smith + snes - the preconditioner context 42286c699258SBarry Smith - dm - the dm 42296c699258SBarry Smith 42306c699258SBarry Smith Level: intermediate 42316c699258SBarry Smith 42326c699258SBarry Smith 42336c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 42346c699258SBarry Smith @*/ 42357087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 42366c699258SBarry Smith { 42376c699258SBarry Smith PetscErrorCode ierr; 4238345fed2cSBarry Smith KSP ksp; 42396cab3a1bSJed Brown SNESDM sdm; 42406c699258SBarry Smith 42416c699258SBarry Smith PetscFunctionBegin; 42420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4243d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 42446cab3a1bSJed Brown if (snes->dm) { /* Move the SNESDM context over to the new DM unless the new DM already has one */ 42456cab3a1bSJed Brown PetscContainer oldcontainer,container; 42466cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 42476cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr); 42486cab3a1bSJed Brown if (oldcontainer && !container) { 42496cab3a1bSJed Brown ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr); 42506cab3a1bSJed Brown ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr); 42516cab3a1bSJed Brown if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */ 42526cab3a1bSJed Brown sdm->originaldm = dm; 42536cab3a1bSJed Brown } 42546cab3a1bSJed Brown } 42556bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 42566cab3a1bSJed Brown } 42576c699258SBarry Smith snes->dm = dm; 4258345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4259345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4260f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 42612c155ee1SBarry Smith if (snes->pc) { 42622c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 42632c155ee1SBarry Smith } 42646c699258SBarry Smith PetscFunctionReturn(0); 42656c699258SBarry Smith } 42666c699258SBarry Smith 42676c699258SBarry Smith #undef __FUNCT__ 42686c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 42696c699258SBarry Smith /*@ 42706c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 42716c699258SBarry Smith 42723f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 42736c699258SBarry Smith 42746c699258SBarry Smith Input Parameter: 42756c699258SBarry Smith . snes - the preconditioner context 42766c699258SBarry Smith 42776c699258SBarry Smith Output Parameter: 42786c699258SBarry Smith . dm - the dm 42796c699258SBarry Smith 42806c699258SBarry Smith Level: intermediate 42816c699258SBarry Smith 42826c699258SBarry Smith 42836c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 42846c699258SBarry Smith @*/ 42857087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 42866c699258SBarry Smith { 42876cab3a1bSJed Brown PetscErrorCode ierr; 42886cab3a1bSJed Brown 42896c699258SBarry Smith PetscFunctionBegin; 42900700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 42916cab3a1bSJed Brown if (!snes->dm) { 42926cab3a1bSJed Brown ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr); 42936cab3a1bSJed Brown } 42946c699258SBarry Smith *dm = snes->dm; 42956c699258SBarry Smith PetscFunctionReturn(0); 42966c699258SBarry Smith } 42970807856dSBarry Smith 429831823bd8SMatthew G Knepley #undef __FUNCT__ 429931823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 430031823bd8SMatthew G Knepley /*@ 4301fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 430231823bd8SMatthew G Knepley 430331823bd8SMatthew G Knepley Collective on SNES 430431823bd8SMatthew G Knepley 430531823bd8SMatthew G Knepley Input Parameters: 430631823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 430731823bd8SMatthew G Knepley - pc - the preconditioner object 430831823bd8SMatthew G Knepley 430931823bd8SMatthew G Knepley Notes: 431031823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 431131823bd8SMatthew G Knepley to configure it using the API). 431231823bd8SMatthew G Knepley 431331823bd8SMatthew G Knepley Level: developer 431431823bd8SMatthew G Knepley 431531823bd8SMatthew G Knepley .keywords: SNES, set, precondition 431631823bd8SMatthew G Knepley .seealso: SNESGetPC() 431731823bd8SMatthew G Knepley @*/ 431831823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 431931823bd8SMatthew G Knepley { 432031823bd8SMatthew G Knepley PetscErrorCode ierr; 432131823bd8SMatthew G Knepley 432231823bd8SMatthew G Knepley PetscFunctionBegin; 432331823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 432431823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 432531823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 432631823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4327bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 432831823bd8SMatthew G Knepley snes->pc = pc; 432931823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 433031823bd8SMatthew G Knepley PetscFunctionReturn(0); 433131823bd8SMatthew G Knepley } 433231823bd8SMatthew G Knepley 433331823bd8SMatthew G Knepley #undef __FUNCT__ 433431823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 433531823bd8SMatthew G Knepley /*@ 4336fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 433731823bd8SMatthew G Knepley 433831823bd8SMatthew G Knepley Not Collective 433931823bd8SMatthew G Knepley 434031823bd8SMatthew G Knepley Input Parameter: 434131823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 434231823bd8SMatthew G Knepley 434331823bd8SMatthew G Knepley Output Parameter: 434431823bd8SMatthew G Knepley . pc - preconditioner context 434531823bd8SMatthew G Knepley 434631823bd8SMatthew G Knepley Level: developer 434731823bd8SMatthew G Knepley 434831823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 434931823bd8SMatthew G Knepley .seealso: SNESSetPC() 435031823bd8SMatthew G Knepley @*/ 435131823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 435231823bd8SMatthew G Knepley { 435331823bd8SMatthew G Knepley PetscErrorCode ierr; 4354*a64e098fSPeter Brune SNESLineSearch linesearch; 4355*a64e098fSPeter Brune SNESLineSearch pclinesearch; 4356*a64e098fSPeter Brune void *lsprectx,*lspostctx; 4357*a64e098fSPeter Brune SNESLineSearchPreCheckFunc lsprefunc; 4358*a64e098fSPeter Brune SNESLineSearchPostCheckFunc lspostfunc; 4359*a64e098fSPeter Brune DM dm; 4360*a64e098fSPeter Brune const char *optionsprefix; 436131823bd8SMatthew G Knepley 436231823bd8SMatthew G Knepley PetscFunctionBegin; 436331823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 436431823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 436531823bd8SMatthew G Knepley if (!snes->pc) { 436631823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm,&snes->pc);CHKERRQ(ierr); 43674a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr); 436831823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes,snes->pc);CHKERRQ(ierr); 4369*a64e098fSPeter Brune ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr); 4370*a64e098fSPeter Brune ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr); 4371*a64e098fSPeter Brune ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr); 4372*a64e098fSPeter Brune 4373*a64e098fSPeter Brune /* copy the DM over */ 4374*a64e098fSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4375*a64e098fSPeter Brune ierr = SNESSetDM(snes->pc,dm);CHKERRQ(ierr); 4376*a64e098fSPeter Brune 4377*a64e098fSPeter Brune /* copy the function pointers over */ 4378*a64e098fSPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr); 4379*a64e098fSPeter Brune 4380*a64e098fSPeter Brune /* default to 1 iteration */ 4381*a64e098fSPeter Brune ierr = SNESSetTolerances(snes->pc, snes->pc->abstol, snes->pc->rtol, snes->pc->stol, 1, snes->pc->max_funcs);CHKERRQ(ierr); 4382*a64e098fSPeter Brune ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); 4383*a64e098fSPeter Brune ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 4384*a64e098fSPeter Brune 4385*a64e098fSPeter Brune 4386*a64e098fSPeter Brune /* copy the line search context over */ 4387*a64e098fSPeter Brune ierr = SNESGetSNESLineSearch(snes,&linesearch);CHKERRQ(ierr); 4388*a64e098fSPeter Brune ierr = SNESGetSNESLineSearch(snes->pc,&pclinesearch);CHKERRQ(ierr); 4389*a64e098fSPeter Brune ierr = SNESLineSearchGetPreCheck(linesearch,&lsprefunc,&lsprectx);CHKERRQ(ierr); 4390*a64e098fSPeter Brune ierr = SNESLineSearchGetPostCheck(linesearch,&lspostfunc,&lspostctx);CHKERRQ(ierr); 4391*a64e098fSPeter Brune ierr = SNESLineSearchSetPreCheck(pclinesearch,lsprefunc,lsprectx);CHKERRQ(ierr); 4392*a64e098fSPeter Brune ierr = SNESLineSearchSetPostCheck(pclinesearch,lspostfunc,lspostctx);CHKERRQ(ierr); 4393*a64e098fSPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr); 439431823bd8SMatthew G Knepley } 439531823bd8SMatthew G Knepley *pc = snes->pc; 439631823bd8SMatthew G Knepley PetscFunctionReturn(0); 439731823bd8SMatthew G Knepley } 439831823bd8SMatthew G Knepley 43999e764e56SPeter Brune #undef __FUNCT__ 4400f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch" 44019e764e56SPeter Brune /*@ 44028141a3b9SPeter Brune SNESSetSNESLineSearch - Sets the linesearch on the SNES instance. 44039e764e56SPeter Brune 44049e764e56SPeter Brune Collective on SNES 44059e764e56SPeter Brune 44069e764e56SPeter Brune Input Parameters: 44079e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 44089e764e56SPeter Brune - linesearch - the linesearch object 44099e764e56SPeter Brune 44109e764e56SPeter Brune Notes: 4411f1c6b773SPeter Brune Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example, 44129e764e56SPeter Brune to configure it using the API). 44139e764e56SPeter Brune 44149e764e56SPeter Brune Level: developer 44159e764e56SPeter Brune 44169e764e56SPeter Brune .keywords: SNES, set, linesearch 4417f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch() 44189e764e56SPeter Brune @*/ 4419f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch) 44209e764e56SPeter Brune { 44219e764e56SPeter Brune PetscErrorCode ierr; 44229e764e56SPeter Brune 44239e764e56SPeter Brune PetscFunctionBegin; 44249e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4425f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 44269e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 44279e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 4428f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 44299e764e56SPeter Brune snes->linesearch = linesearch; 44309e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 44319e764e56SPeter Brune PetscFunctionReturn(0); 44329e764e56SPeter Brune } 44339e764e56SPeter Brune 44349e764e56SPeter Brune #undef __FUNCT__ 4435f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch" 4436ea5d4fccSPeter Brune /*@C 44378141a3b9SPeter Brune SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 44388141a3b9SPeter Brune or creates a default line search instance associated with the SNES and returns it. 44399e764e56SPeter Brune 44409e764e56SPeter Brune Not Collective 44419e764e56SPeter Brune 44429e764e56SPeter Brune Input Parameter: 44439e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 44449e764e56SPeter Brune 44459e764e56SPeter Brune Output Parameter: 44469e764e56SPeter Brune . linesearch - linesearch context 44479e764e56SPeter Brune 44489e764e56SPeter Brune Level: developer 44499e764e56SPeter Brune 44509e764e56SPeter Brune .keywords: SNES, get, linesearch 4451f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch() 44529e764e56SPeter Brune @*/ 4453f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch) 44549e764e56SPeter Brune { 44559e764e56SPeter Brune PetscErrorCode ierr; 44569e764e56SPeter Brune const char *optionsprefix; 44579e764e56SPeter Brune 44589e764e56SPeter Brune PetscFunctionBegin; 44599e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 44609e764e56SPeter Brune PetscValidPointer(linesearch, 2); 44619e764e56SPeter Brune if (!snes->linesearch) { 44629e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 4463f1c6b773SPeter Brune ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr); 4464f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 4465b1dca40bSPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 44669e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 44679e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 44689e764e56SPeter Brune } 44699e764e56SPeter Brune *linesearch = snes->linesearch; 44709e764e56SPeter Brune PetscFunctionReturn(0); 44719e764e56SPeter Brune } 44729e764e56SPeter Brune 447369b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4474c6db04a5SJed Brown #include <mex.h> 447569b4f73cSBarry Smith 44768f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 44778f6e6473SBarry Smith 44780807856dSBarry Smith #undef __FUNCT__ 44790807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 44800807856dSBarry Smith /* 44810807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 44820807856dSBarry Smith SNESSetFunctionMatlab(). 44830807856dSBarry Smith 44840807856dSBarry Smith Collective on SNES 44850807856dSBarry Smith 44860807856dSBarry Smith Input Parameters: 44870807856dSBarry Smith + snes - the SNES context 44880807856dSBarry Smith - x - input vector 44890807856dSBarry Smith 44900807856dSBarry Smith Output Parameter: 44910807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 44920807856dSBarry Smith 44930807856dSBarry Smith Notes: 44940807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 44950807856dSBarry Smith implementations, so most users would not generally call this routine 44960807856dSBarry Smith themselves. 44970807856dSBarry Smith 44980807856dSBarry Smith Level: developer 44990807856dSBarry Smith 45000807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 45010807856dSBarry Smith 45020807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 450361b2408cSBarry Smith */ 45047087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 45050807856dSBarry Smith { 4506e650e774SBarry Smith PetscErrorCode ierr; 45078f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 45088f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 45098f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 451091621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 4511e650e774SBarry Smith 45120807856dSBarry Smith PetscFunctionBegin; 45130807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 45140807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 45150807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 45160807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 45170807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 45180807856dSBarry Smith 45190807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 4520e650e774SBarry Smith 452191621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4522e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4523e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 452491621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 452591621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 452691621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 45278f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 45288f6e6473SBarry Smith prhs[4] = sctx->ctx; 4529b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 4530e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4531e650e774SBarry Smith mxDestroyArray(prhs[0]); 4532e650e774SBarry Smith mxDestroyArray(prhs[1]); 4533e650e774SBarry Smith mxDestroyArray(prhs[2]); 45348f6e6473SBarry Smith mxDestroyArray(prhs[3]); 4535e650e774SBarry Smith mxDestroyArray(plhs[0]); 45360807856dSBarry Smith PetscFunctionReturn(0); 45370807856dSBarry Smith } 45380807856dSBarry Smith 45390807856dSBarry Smith 45400807856dSBarry Smith #undef __FUNCT__ 45410807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 454261b2408cSBarry Smith /* 45430807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 45440807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4545e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 45460807856dSBarry Smith 45470807856dSBarry Smith Logically Collective on SNES 45480807856dSBarry Smith 45490807856dSBarry Smith Input Parameters: 45500807856dSBarry Smith + snes - the SNES context 45510807856dSBarry Smith . r - vector to store function value 45520807856dSBarry Smith - func - function evaluation routine 45530807856dSBarry Smith 45540807856dSBarry Smith Calling sequence of func: 455561b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 45560807856dSBarry Smith 45570807856dSBarry Smith 45580807856dSBarry Smith Notes: 45590807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 45600807856dSBarry Smith $ f'(x) x = -f(x), 45610807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 45620807856dSBarry Smith 45630807856dSBarry Smith Level: beginner 45640807856dSBarry Smith 45650807856dSBarry Smith .keywords: SNES, nonlinear, set, function 45660807856dSBarry Smith 45670807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 456861b2408cSBarry Smith */ 45697087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 45700807856dSBarry Smith { 45710807856dSBarry Smith PetscErrorCode ierr; 45728f6e6473SBarry Smith SNESMatlabContext *sctx; 45730807856dSBarry Smith 45740807856dSBarry Smith PetscFunctionBegin; 45758f6e6473SBarry Smith /* currently sctx is memory bleed */ 45768f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 45778f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 45788f6e6473SBarry Smith /* 45798f6e6473SBarry Smith This should work, but it doesn't 45808f6e6473SBarry Smith sctx->ctx = ctx; 45818f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 45828f6e6473SBarry Smith */ 45838f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 45848f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 45850807856dSBarry Smith PetscFunctionReturn(0); 45860807856dSBarry Smith } 458769b4f73cSBarry Smith 458861b2408cSBarry Smith #undef __FUNCT__ 458961b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 459061b2408cSBarry Smith /* 459161b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 459261b2408cSBarry Smith SNESSetJacobianMatlab(). 459361b2408cSBarry Smith 459461b2408cSBarry Smith Collective on SNES 459561b2408cSBarry Smith 459661b2408cSBarry Smith Input Parameters: 459761b2408cSBarry Smith + snes - the SNES context 459861b2408cSBarry Smith . x - input vector 459961b2408cSBarry Smith . A, B - the matrices 460061b2408cSBarry Smith - ctx - user context 460161b2408cSBarry Smith 460261b2408cSBarry Smith Output Parameter: 460361b2408cSBarry Smith . flag - structure of the matrix 460461b2408cSBarry Smith 460561b2408cSBarry Smith Level: developer 460661b2408cSBarry Smith 460761b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 460861b2408cSBarry Smith 460961b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 461061b2408cSBarry Smith @*/ 46117087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 461261b2408cSBarry Smith { 461361b2408cSBarry Smith PetscErrorCode ierr; 461461b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 461561b2408cSBarry Smith int nlhs = 2,nrhs = 6; 461661b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 461761b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 461861b2408cSBarry Smith 461961b2408cSBarry Smith PetscFunctionBegin; 462061b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 462161b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 462261b2408cSBarry Smith 462361b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 462461b2408cSBarry Smith 462561b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 462661b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 462761b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 462861b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 462961b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 463061b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 463161b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 463261b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 463361b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 463461b2408cSBarry Smith prhs[5] = sctx->ctx; 4635b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 463661b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 463761b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 463861b2408cSBarry Smith mxDestroyArray(prhs[0]); 463961b2408cSBarry Smith mxDestroyArray(prhs[1]); 464061b2408cSBarry Smith mxDestroyArray(prhs[2]); 464161b2408cSBarry Smith mxDestroyArray(prhs[3]); 464261b2408cSBarry Smith mxDestroyArray(prhs[4]); 464361b2408cSBarry Smith mxDestroyArray(plhs[0]); 464461b2408cSBarry Smith mxDestroyArray(plhs[1]); 464561b2408cSBarry Smith PetscFunctionReturn(0); 464661b2408cSBarry Smith } 464761b2408cSBarry Smith 464861b2408cSBarry Smith 464961b2408cSBarry Smith #undef __FUNCT__ 465061b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 465161b2408cSBarry Smith /* 465261b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 465361b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4654e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 465561b2408cSBarry Smith 465661b2408cSBarry Smith Logically Collective on SNES 465761b2408cSBarry Smith 465861b2408cSBarry Smith Input Parameters: 465961b2408cSBarry Smith + snes - the SNES context 466061b2408cSBarry Smith . A,B - Jacobian matrices 466161b2408cSBarry Smith . func - function evaluation routine 466261b2408cSBarry Smith - ctx - user context 466361b2408cSBarry Smith 466461b2408cSBarry Smith Calling sequence of func: 466561b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 466661b2408cSBarry Smith 466761b2408cSBarry Smith 466861b2408cSBarry Smith Level: developer 466961b2408cSBarry Smith 467061b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 467161b2408cSBarry Smith 467261b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 467361b2408cSBarry Smith */ 46747087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 467561b2408cSBarry Smith { 467661b2408cSBarry Smith PetscErrorCode ierr; 467761b2408cSBarry Smith SNESMatlabContext *sctx; 467861b2408cSBarry Smith 467961b2408cSBarry Smith PetscFunctionBegin; 468061b2408cSBarry Smith /* currently sctx is memory bleed */ 468161b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 468261b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 468361b2408cSBarry Smith /* 468461b2408cSBarry Smith This should work, but it doesn't 468561b2408cSBarry Smith sctx->ctx = ctx; 468661b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 468761b2408cSBarry Smith */ 468861b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 468961b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 469061b2408cSBarry Smith PetscFunctionReturn(0); 469161b2408cSBarry Smith } 469269b4f73cSBarry Smith 4693f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4694f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4695f9eb7ae2SShri Abhyankar /* 4696f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4697f9eb7ae2SShri Abhyankar 4698f9eb7ae2SShri Abhyankar Collective on SNES 4699f9eb7ae2SShri Abhyankar 4700f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4701f9eb7ae2SShri Abhyankar @*/ 47027087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4703f9eb7ae2SShri Abhyankar { 4704f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 470548f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4706f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4707f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4708f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4709f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4710f9eb7ae2SShri Abhyankar 4711f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4712f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4713f9eb7ae2SShri Abhyankar 4714f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4715f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4716f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4717f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4718f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4719f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4720f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4721f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4722f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4723f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4724f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4725f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4726f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4727f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4728f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4729f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4730f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4731f9eb7ae2SShri Abhyankar } 4732f9eb7ae2SShri Abhyankar 4733f9eb7ae2SShri Abhyankar 4734f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4735f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4736f9eb7ae2SShri Abhyankar /* 4737e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4738f9eb7ae2SShri Abhyankar 4739f9eb7ae2SShri Abhyankar Level: developer 4740f9eb7ae2SShri Abhyankar 4741f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4742f9eb7ae2SShri Abhyankar 4743f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4744f9eb7ae2SShri Abhyankar */ 47457087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4746f9eb7ae2SShri Abhyankar { 4747f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4748f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4749f9eb7ae2SShri Abhyankar 4750f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4751f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4752f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4753f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4754f9eb7ae2SShri Abhyankar /* 4755f9eb7ae2SShri Abhyankar This should work, but it doesn't 4756f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4757f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4758f9eb7ae2SShri Abhyankar */ 4759f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4760f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4761f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4762f9eb7ae2SShri Abhyankar } 4763f9eb7ae2SShri Abhyankar 476469b4f73cSBarry Smith #endif 4765