19b94acceSBarry Smith 2c6db04a5SJed Brown #include <private/snesimpl.h> /*I "petscsnes.h" I*/ 36cab3a1bSJed Brown #include <petscdmshell.h> /*I "petscdmshell.h" I*/ 49b94acceSBarry Smith 5ace3abfcSBarry Smith PetscBool SNESRegisterAllCalled = PETSC_FALSE; 68ba1e511SMatthew Knepley PetscFList SNESList = PETSC_NULL; 78ba1e511SMatthew Knepley 88ba1e511SMatthew Knepley /* Logging support */ 97087cfbeSBarry Smith PetscClassId SNES_CLASSID; 10701cf23dSPeter Brune PetscLogEvent SNES_Solve, SNES_LineSearch, SNES_FunctionEval, SNES_JacobianEval, SNES_GSEval; 11a09944afSBarry Smith 12a09944afSBarry Smith #undef __FUNCT__ 13cab2e9ccSBarry Smith #define __FUNCT__ "SNESDMComputeJacobian" 14cab2e9ccSBarry Smith /* 15cab2e9ccSBarry Smith Translates from a SNES call to a DM call in computing a Jacobian 16cab2e9ccSBarry Smith */ 17cab2e9ccSBarry Smith PetscErrorCode SNESDMComputeJacobian(SNES snes,Vec X,Mat *J,Mat *B,MatStructure *flag,void *ptr) 18cab2e9ccSBarry Smith { 19cab2e9ccSBarry Smith PetscErrorCode ierr; 20cab2e9ccSBarry Smith DM dm; 21cab2e9ccSBarry Smith 22cab2e9ccSBarry Smith PetscFunctionBegin; 23cab2e9ccSBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 24cab2e9ccSBarry Smith ierr = DMComputeJacobian(dm,X,*J,*B,flag);CHKERRQ(ierr); 25cab2e9ccSBarry Smith PetscFunctionReturn(0); 26cab2e9ccSBarry Smith } 27cab2e9ccSBarry Smith 28cab2e9ccSBarry Smith #undef __FUNCT__ 29e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged" 30e113a28aSBarry Smith /*@ 31e113a28aSBarry Smith SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged. 32e113a28aSBarry Smith 333f9fe445SBarry Smith Logically Collective on SNES 34e113a28aSBarry Smith 35e113a28aSBarry Smith Input Parameters: 36e113a28aSBarry Smith + snes - iterative context obtained from SNESCreate() 37e113a28aSBarry Smith - flg - PETSC_TRUE indicates you want the error generated 38e113a28aSBarry Smith 39e113a28aSBarry Smith Options database keys: 40e113a28aSBarry Smith . -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false) 41e113a28aSBarry Smith 42e113a28aSBarry Smith Level: intermediate 43e113a28aSBarry Smith 44e113a28aSBarry Smith Notes: 45e113a28aSBarry Smith Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve() 46e113a28aSBarry Smith to determine if it has converged. 47e113a28aSBarry Smith 48e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 49e113a28aSBarry Smith 50e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 51e113a28aSBarry Smith @*/ 527087cfbeSBarry Smith PetscErrorCode SNESSetErrorIfNotConverged(SNES snes,PetscBool flg) 53e113a28aSBarry Smith { 54e113a28aSBarry Smith PetscFunctionBegin; 55e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 56acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flg,2); 57e113a28aSBarry Smith snes->errorifnotconverged = flg; 58dd568438SSatish Balay 59e113a28aSBarry Smith PetscFunctionReturn(0); 60e113a28aSBarry Smith } 61e113a28aSBarry Smith 62e113a28aSBarry Smith #undef __FUNCT__ 63e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged" 64e113a28aSBarry Smith /*@ 65e113a28aSBarry Smith SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge? 66e113a28aSBarry Smith 67e113a28aSBarry Smith Not Collective 68e113a28aSBarry Smith 69e113a28aSBarry Smith Input Parameter: 70e113a28aSBarry Smith . snes - iterative context obtained from SNESCreate() 71e113a28aSBarry Smith 72e113a28aSBarry Smith Output Parameter: 73e113a28aSBarry Smith . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE 74e113a28aSBarry Smith 75e113a28aSBarry Smith Level: intermediate 76e113a28aSBarry Smith 77e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 78e113a28aSBarry Smith 79e113a28aSBarry Smith .seealso: SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 80e113a28aSBarry Smith @*/ 817087cfbeSBarry Smith PetscErrorCode SNESGetErrorIfNotConverged(SNES snes,PetscBool *flag) 82e113a28aSBarry Smith { 83e113a28aSBarry Smith PetscFunctionBegin; 84e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 85e113a28aSBarry Smith PetscValidPointer(flag,2); 86e113a28aSBarry Smith *flag = snes->errorifnotconverged; 87e113a28aSBarry Smith PetscFunctionReturn(0); 88e113a28aSBarry Smith } 89e113a28aSBarry Smith 90e113a28aSBarry Smith #undef __FUNCT__ 914936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError" 92e725d27bSBarry Smith /*@ 934936397dSBarry Smith SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not 944936397dSBarry Smith in the functions domain. For example, negative pressure. 954936397dSBarry Smith 963f9fe445SBarry Smith Logically Collective on SNES 974936397dSBarry Smith 984936397dSBarry Smith Input Parameters: 99*6a388c36SPeter Brune . snes - the SNES context 1004936397dSBarry Smith 10128529972SSatish Balay Level: advanced 1024936397dSBarry Smith 1034936397dSBarry Smith .keywords: SNES, view 1044936397dSBarry Smith 1054936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction() 1064936397dSBarry Smith @*/ 1077087cfbeSBarry Smith PetscErrorCode SNESSetFunctionDomainError(SNES snes) 1084936397dSBarry Smith { 1094936397dSBarry Smith PetscFunctionBegin; 1100700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1114936397dSBarry Smith snes->domainerror = PETSC_TRUE; 1124936397dSBarry Smith PetscFunctionReturn(0); 1134936397dSBarry Smith } 1144936397dSBarry Smith 115*6a388c36SPeter Brune 116*6a388c36SPeter Brune #undef __FUNCT__ 117*6a388c36SPeter Brune #define __FUNCT__ "SNESGetFunctionDomainError" 118*6a388c36SPeter Brune /*@ 119*6a388c36SPeter Brune SNESSetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction; 120*6a388c36SPeter Brune 121*6a388c36SPeter Brune Logically Collective on SNES 122*6a388c36SPeter Brune 123*6a388c36SPeter Brune Input Parameters: 124*6a388c36SPeter Brune . snes - the SNES context 125*6a388c36SPeter Brune 126*6a388c36SPeter Brune Output Parameters: 127*6a388c36SPeter Brune . domainerror Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise. 128*6a388c36SPeter Brune 129*6a388c36SPeter Brune Level: advanced 130*6a388c36SPeter Brune 131*6a388c36SPeter Brune .keywords: SNES, view 132*6a388c36SPeter Brune 133*6a388c36SPeter Brune .seealso: SNESSetFunctionDomainError, SNESComputeFunction() 134*6a388c36SPeter Brune @*/ 135*6a388c36SPeter Brune PetscErrorCode SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror) 136*6a388c36SPeter Brune { 137*6a388c36SPeter Brune PetscFunctionBegin; 138*6a388c36SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 139*6a388c36SPeter Brune PetscValidPointer(domainerror, 2); 140*6a388c36SPeter Brune *domainerror = snes->domainerror; 141*6a388c36SPeter Brune PetscFunctionReturn(0); 142*6a388c36SPeter Brune } 143*6a388c36SPeter Brune 144*6a388c36SPeter Brune 1454936397dSBarry Smith #undef __FUNCT__ 1464a2ae208SSatish Balay #define __FUNCT__ "SNESView" 1477e2c5f70SBarry Smith /*@C 1489b94acceSBarry Smith SNESView - Prints the SNES data structure. 1499b94acceSBarry Smith 1504c49b128SBarry Smith Collective on SNES 151fee21e36SBarry Smith 152c7afd0dbSLois Curfman McInnes Input Parameters: 153c7afd0dbSLois Curfman McInnes + SNES - the SNES context 154c7afd0dbSLois Curfman McInnes - viewer - visualization context 155c7afd0dbSLois Curfman McInnes 1569b94acceSBarry Smith Options Database Key: 157c8a8ba5cSLois Curfman McInnes . -snes_view - Calls SNESView() at end of SNESSolve() 1589b94acceSBarry Smith 1599b94acceSBarry Smith Notes: 1609b94acceSBarry Smith The available visualization contexts include 161b0a32e0cSBarry Smith + PETSC_VIEWER_STDOUT_SELF - standard output (default) 162b0a32e0cSBarry Smith - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 163c8a8ba5cSLois Curfman McInnes output where only the first processor opens 164c8a8ba5cSLois Curfman McInnes the file. All other processors send their 165c8a8ba5cSLois Curfman McInnes data to the first processor to print. 1669b94acceSBarry Smith 1673e081fefSLois Curfman McInnes The user can open an alternative visualization context with 168b0a32e0cSBarry Smith PetscViewerASCIIOpen() - output to a specified file. 1699b94acceSBarry Smith 17036851e7fSLois Curfman McInnes Level: beginner 17136851e7fSLois Curfman McInnes 1729b94acceSBarry Smith .keywords: SNES, view 1739b94acceSBarry Smith 174b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen() 1759b94acceSBarry Smith @*/ 1767087cfbeSBarry Smith PetscErrorCode SNESView(SNES snes,PetscViewer viewer) 1779b94acceSBarry Smith { 178fa9f3622SBarry Smith SNESKSPEW *kctx; 179dfbe8321SBarry Smith PetscErrorCode ierr; 18094b7f48cSBarry Smith KSP ksp; 181ace3abfcSBarry Smith PetscBool iascii,isstring; 1829b94acceSBarry Smith 1833a40ed3dSBarry Smith PetscFunctionBegin; 1840700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1853050cee2SBarry Smith if (!viewer) { 1867adad957SLisandro Dalcin ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 1873050cee2SBarry Smith } 1880700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 189c9780b6fSBarry Smith PetscCheckSameComm(snes,1,viewer,2); 19074679c65SBarry Smith 1912692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1922692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 19332077d6dSBarry Smith if (iascii) { 194317d6ea6SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr); 195e7788613SBarry Smith if (snes->ops->view) { 196b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 197e7788613SBarry Smith ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 198b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1990ef38995SBarry Smith } 20077431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr); 201a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%G, absolute=%G, solution=%G\n", 20270441072SBarry Smith snes->rtol,snes->abstol,snes->xtol);CHKERRQ(ierr); 20377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr); 20477431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr); 2059b94acceSBarry Smith if (snes->ksp_ewconv) { 206fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 2079b94acceSBarry Smith if (kctx) { 20877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr); 209a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr); 210a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr); 2119b94acceSBarry Smith } 2129b94acceSBarry Smith } 213eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 214eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n");CHKERRQ(ierr); 215eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 216eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr); 217eb1f6c34SBarry Smith } 218eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 219eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n");CHKERRQ(ierr); 220eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 22142f4f86dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr); 222eb1f6c34SBarry Smith } 2230f5bd95cSBarry Smith } else if (isstring) { 224317d6ea6SBarry Smith const char *type; 225454a90a3SBarry Smith ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 226b0a32e0cSBarry Smith ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr); 22719bcc07fSBarry Smith } 22842f4f86dSBarry Smith if (snes->pc && snes->usespc) { 2294a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2304a0c5b0cSMatthew G Knepley ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr); 2314a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2324a0c5b0cSMatthew G Knepley } 2332c155ee1SBarry Smith if (snes->usesksp) { 2342c155ee1SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 235b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 23694b7f48cSBarry Smith ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 237b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2382c155ee1SBarry Smith } 2393a40ed3dSBarry Smith PetscFunctionReturn(0); 2409b94acceSBarry Smith } 2419b94acceSBarry Smith 24276b2cf59SMatthew Knepley /* 24376b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 24476b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 24576b2cf59SMatthew Knepley */ 24676b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 247a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 2486849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 24976b2cf59SMatthew Knepley 250e74ef692SMatthew Knepley #undef __FUNCT__ 251e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker" 252ac226902SBarry Smith /*@C 25376b2cf59SMatthew Knepley SNESAddOptionsChecker - Adds an additional function to check for SNES options. 25476b2cf59SMatthew Knepley 25576b2cf59SMatthew Knepley Not Collective 25676b2cf59SMatthew Knepley 25776b2cf59SMatthew Knepley Input Parameter: 25876b2cf59SMatthew Knepley . snescheck - function that checks for options 25976b2cf59SMatthew Knepley 26076b2cf59SMatthew Knepley Level: developer 26176b2cf59SMatthew Knepley 26276b2cf59SMatthew Knepley .seealso: SNESSetFromOptions() 26376b2cf59SMatthew Knepley @*/ 2647087cfbeSBarry Smith PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 26576b2cf59SMatthew Knepley { 26676b2cf59SMatthew Knepley PetscFunctionBegin; 26776b2cf59SMatthew Knepley if (numberofsetfromoptions >= MAXSETFROMOPTIONS) { 268e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 26976b2cf59SMatthew Knepley } 27076b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 27176b2cf59SMatthew Knepley PetscFunctionReturn(0); 27276b2cf59SMatthew Knepley } 27376b2cf59SMatthew Knepley 2747087cfbeSBarry Smith extern PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 275aa3661deSLisandro Dalcin 276aa3661deSLisandro Dalcin #undef __FUNCT__ 277aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private" 278ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 279aa3661deSLisandro Dalcin { 280aa3661deSLisandro Dalcin Mat J; 281aa3661deSLisandro Dalcin KSP ksp; 282aa3661deSLisandro Dalcin PC pc; 283ace3abfcSBarry Smith PetscBool match; 284aa3661deSLisandro Dalcin PetscErrorCode ierr; 285aa3661deSLisandro Dalcin 286aa3661deSLisandro Dalcin PetscFunctionBegin; 2870700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 288aa3661deSLisandro Dalcin 28998613b67SLisandro Dalcin if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 29098613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 29198613b67SLisandro Dalcin ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr); 29298613b67SLisandro Dalcin } 29398613b67SLisandro Dalcin 294aa3661deSLisandro Dalcin if (version == 1) { 295aa3661deSLisandro Dalcin ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 29698613b67SLisandro Dalcin ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 2979c6ac3b3SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 298aa3661deSLisandro Dalcin } else if (version == 2) { 299e32f2f54SBarry Smith if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 30082a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 301aa3661deSLisandro Dalcin ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr); 302aa3661deSLisandro Dalcin #else 303e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)"); 304aa3661deSLisandro Dalcin #endif 305a8248277SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2"); 306aa3661deSLisandro Dalcin 307aa3661deSLisandro Dalcin ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr); 308d3462f78SMatthew Knepley if (hasOperator) { 309aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 310aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 311aa3661deSLisandro Dalcin ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 312aa3661deSLisandro Dalcin } else { 313aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 314aa3661deSLisandro Dalcin provided preconditioner matrix with the default matrix free version. */ 3156cab3a1bSJed Brown void *functx; 3166cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 3176cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr); 318aa3661deSLisandro Dalcin /* Force no preconditioner */ 319aa3661deSLisandro Dalcin ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 320aa3661deSLisandro Dalcin ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 321aa3661deSLisandro Dalcin ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr); 322aa3661deSLisandro Dalcin if (!match) { 323aa3661deSLisandro Dalcin ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 324aa3661deSLisandro Dalcin ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 325aa3661deSLisandro Dalcin } 326aa3661deSLisandro Dalcin } 3276bf464f9SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 328aa3661deSLisandro Dalcin PetscFunctionReturn(0); 329aa3661deSLisandro Dalcin } 330aa3661deSLisandro Dalcin 3314a2ae208SSatish Balay #undef __FUNCT__ 3326cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices" 3336cab3a1bSJed Brown /*@ 3346cab3a1bSJed Brown SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX() 3356cab3a1bSJed Brown 3366cab3a1bSJed Brown Collective 3376cab3a1bSJed Brown 3386cab3a1bSJed Brown Input Arguments: 3396cab3a1bSJed Brown . snes - snes to configure 3406cab3a1bSJed Brown 3416cab3a1bSJed Brown Level: developer 3426cab3a1bSJed Brown 3436cab3a1bSJed Brown .seealso: SNESSetUp() 3446cab3a1bSJed Brown @*/ 3456cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes) 3466cab3a1bSJed Brown { 3476cab3a1bSJed Brown PetscErrorCode ierr; 3486cab3a1bSJed Brown DM dm; 3496cab3a1bSJed Brown SNESDM sdm; 3506cab3a1bSJed Brown 3516cab3a1bSJed Brown PetscFunctionBegin; 3526cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3536cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 3546cab3a1bSJed Brown if (!sdm->computejacobian && snes->dm) { 3556cab3a1bSJed Brown Mat J,B; 3566cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 3576cab3a1bSJed Brown if (snes->mf_operator) { 3586cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 3596cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 3606cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 3616cab3a1bSJed Brown } else { 3626cab3a1bSJed Brown J = B; 3636cab3a1bSJed Brown ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr); 3646cab3a1bSJed Brown } 3656cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr); 3666cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 3676cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 3686cab3a1bSJed Brown } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) { 3696cab3a1bSJed Brown Mat J; 3706cab3a1bSJed Brown void *functx; 3716cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 3726cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 3736cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 3746cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 3756cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr); 3766cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 3776cab3a1bSJed Brown } else if (snes->dm && snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 3786cab3a1bSJed Brown Mat J,B; 3796cab3a1bSJed Brown void *functx; 3806cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 3816cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 3826cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 3836cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 3846cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 3856cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,functx);CHKERRQ(ierr); 3866cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 3876cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 3886cab3a1bSJed Brown } else if (snes->dm && !snes->jacobian_pre) { 3896cab3a1bSJed Brown Mat J,B; 3906cab3a1bSJed Brown J = snes->jacobian; 3916cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 3926cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 3936cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 3946cab3a1bSJed Brown } 3956cab3a1bSJed Brown PetscFunctionReturn(0); 3966cab3a1bSJed Brown } 3976cab3a1bSJed Brown 3986cab3a1bSJed Brown #undef __FUNCT__ 3994a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions" 4009b94acceSBarry Smith /*@ 40194b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 4029b94acceSBarry Smith 403c7afd0dbSLois Curfman McInnes Collective on SNES 404c7afd0dbSLois Curfman McInnes 4059b94acceSBarry Smith Input Parameter: 4069b94acceSBarry Smith . snes - the SNES context 4079b94acceSBarry Smith 40836851e7fSLois Curfman McInnes Options Database Keys: 409ea630c6eSPeter Brune + -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas 41082738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 41182738288SBarry Smith of the change in the solution between steps 41270441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 413b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 414b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 415b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 4164839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 417ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 418a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 419e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 420b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 4212492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 42282738288SBarry Smith solver; hence iterations will continue until max_it 4231fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 42482738288SBarry Smith of convergence test 425e8105e01SRichard Katz . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 426e8105e01SRichard Katz filename given prints to stdout 427a6570f20SBarry Smith . -snes_monitor_solution - plots solution at each iteration 428a6570f20SBarry Smith . -snes_monitor_residual - plots residual (not its norm) at each iteration 429a6570f20SBarry Smith . -snes_monitor_solution_update - plots update to solution at each iteration 430a6570f20SBarry Smith . -snes_monitor_draw - plots residual norm at each iteration 431e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 4325968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 433fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 43482738288SBarry Smith 43582738288SBarry Smith Options Database for Eisenstat-Walker method: 436fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 4374b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 43836851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 43936851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 44036851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 44136851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 44236851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 44336851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 44482738288SBarry Smith 44511ca99fdSLois Curfman McInnes Notes: 44611ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 4470598bfebSBarry Smith the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>. 44883e2fdc7SBarry Smith 44936851e7fSLois Curfman McInnes Level: beginner 45036851e7fSLois Curfman McInnes 4519b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 4529b94acceSBarry Smith 45369ed319cSSatish Balay .seealso: SNESSetOptionsPrefix() 4549b94acceSBarry Smith @*/ 4557087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 4569b94acceSBarry Smith { 457ea630c6eSPeter Brune PetscBool flg,set,mf,mf_operator,pcset; 458efd51863SBarry Smith PetscInt i,indx,lag,mf_version,grids; 459aa3661deSLisandro Dalcin MatStructure matflag; 46085385478SLisandro Dalcin const char *deft = SNESLS; 46185385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 46285385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 463e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 46451e86f29SPeter Brune const char *optionsprefix; 465649052a6SBarry Smith PetscViewer monviewer; 46685385478SLisandro Dalcin PetscErrorCode ierr; 4679b94acceSBarry Smith 4683a40ed3dSBarry Smith PetscFunctionBegin; 4690700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 470ca161407SBarry Smith 471186905e3SBarry Smith if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 4723194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 4737adad957SLisandro Dalcin if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; } 474b0a32e0cSBarry Smith ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 475d64ed03dSBarry Smith if (flg) { 476186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 4777adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 478186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 479d64ed03dSBarry Smith } 48090d69ab7SBarry Smith /* not used here, but called so will go into help messaage */ 481909c8a9fSBarry Smith ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 48293c39befSBarry Smith 48357034d6fSHong Zhang ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->xtol,&snes->xtol,0);CHKERRQ(ierr); 48457034d6fSHong Zhang ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 485186905e3SBarry Smith 48657034d6fSHong Zhang ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 487b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 488b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 48950ffb88aSMatthew Knepley ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 490ddf469c8SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr); 491acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr); 49285385478SLisandro Dalcin 493a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 494a8054027SBarry Smith if (flg) { 495a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 496a8054027SBarry Smith } 497e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 498e35cf81dSBarry Smith if (flg) { 499e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 500e35cf81dSBarry Smith } 501efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 502efd51863SBarry Smith if (flg) { 503efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 504efd51863SBarry Smith } 505a8054027SBarry Smith 50685385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 50785385478SLisandro Dalcin if (flg) { 50885385478SLisandro Dalcin switch (indx) { 5097f7931b9SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 5107f7931b9SBarry Smith case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 51185385478SLisandro Dalcin } 51285385478SLisandro Dalcin } 51385385478SLisandro Dalcin 514acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr); 515186905e3SBarry Smith 51685385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 51785385478SLisandro Dalcin 518acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 519186905e3SBarry Smith 520fa9f3622SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 521fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 522fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 523fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 524fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 525fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 526fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 527186905e3SBarry Smith 52890d69ab7SBarry Smith flg = PETSC_FALSE; 529acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 530a6570f20SBarry Smith if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 531eabae89aSBarry Smith 532a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 533e8105e01SRichard Katz if (flg) { 534649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 535649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 536e8105e01SRichard Katz } 537eabae89aSBarry Smith 538b271bb04SBarry Smith ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 539b271bb04SBarry Smith if (flg) { 540b271bb04SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 541b271bb04SBarry Smith } 542b271bb04SBarry Smith 543a6570f20SBarry Smith ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 544eabae89aSBarry Smith if (flg) { 545649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 546f1bef1bcSMatthew Knepley ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 547e8105e01SRichard Katz } 548eabae89aSBarry Smith 549a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 550eabae89aSBarry Smith if (flg) { 551649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 552649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 553eabae89aSBarry Smith } 554eabae89aSBarry Smith 5555180491cSLisandro Dalcin ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 5565180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 5575180491cSLisandro Dalcin 55890d69ab7SBarry Smith flg = PETSC_FALSE; 559acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 560a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 56190d69ab7SBarry Smith flg = PETSC_FALSE; 562acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 563a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 56490d69ab7SBarry Smith flg = PETSC_FALSE; 565acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 566a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 56790d69ab7SBarry Smith flg = PETSC_FALSE; 568acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 569a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 57090d69ab7SBarry Smith flg = PETSC_FALSE; 571acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 572b271bb04SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 573e24b481bSBarry Smith 57490d69ab7SBarry Smith flg = PETSC_FALSE; 575acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 5764b27c08aSLois Curfman McInnes if (flg) { 5776cab3a1bSJed Brown void *functx; 5786cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 5796cab3a1bSJed Brown ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr); 580ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 5819b94acceSBarry Smith } 582639f9d9dSBarry Smith 583aa3661deSLisandro Dalcin mf = mf_operator = PETSC_FALSE; 584aa3661deSLisandro Dalcin flg = PETSC_FALSE; 585acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr); 586a8248277SBarry Smith if (flg && mf_operator) { 587a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 588a8248277SBarry Smith mf = PETSC_TRUE; 589a8248277SBarry Smith } 590aa3661deSLisandro Dalcin flg = PETSC_FALSE; 591acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr); 592aa3661deSLisandro Dalcin if (!flg && mf_operator) mf = PETSC_TRUE; 593aa3661deSLisandro Dalcin mf_version = 1; 594aa3661deSLisandro Dalcin ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr); 595aa3661deSLisandro Dalcin 596d28543b3SPeter Brune 59789b92e6fSPeter Brune /* GS Options */ 59889b92e6fSPeter Brune ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr); 59989b92e6fSPeter Brune 600ea630c6eSPeter Brune /* line search options */ 601ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_alpha","Constant function norm must decrease by","None",snes->ls_alpha,&snes->ls_alpha,0);CHKERRQ(ierr); 602ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_maxstep","Step must be less than","None",snes->maxstep,&snes->maxstep,0);CHKERRQ(ierr); 603ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_steptol","Minimum lambda allowed","None",snes->steptol,&snes->steptol,0);CHKERRQ(ierr); 604ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_damping","Damping parameter","SNES",snes->damping,&snes->damping,&flg);CHKERRQ(ierr); 605af60355fSPeter Brune ierr = PetscOptionsInt("-snes_ls_it" ,"Line search iterations","SNES",snes->ls_its,&snes->ls_its,&flg);CHKERRQ(ierr); 606ea630c6eSPeter Brune ierr = PetscOptionsBool("-snes_ls_monitor","Print progress of line searches","SNESLineSearchSetMonitor",snes->ls_monitor ? PETSC_TRUE : PETSC_FALSE,&flg,&set);CHKERRQ(ierr); 607ea630c6eSPeter Brune if (set) {ierr = SNESLineSearchSetMonitor(snes,flg);CHKERRQ(ierr);} 60815f5eeeaSPeter Brune ierr = PetscOptionsEnum("-snes_ls","Line search used","SNESLineSearchSet",SNESLineSearchTypes,(PetscEnum)snes->ls_type,(PetscEnum*)&indx,&flg);CHKERRQ(ierr); 60915f5eeeaSPeter Brune if (flg) { 610ea630c6eSPeter Brune ierr = SNESLineSearchSetType(snes,(SNESLineSearchType)indx);CHKERRQ(ierr); 61115f5eeeaSPeter Brune } 6128e3fc8c0SJed Brown flg = snes->ops->precheckstep == SNESLineSearchPreCheckPicard ? PETSC_TRUE : PETSC_FALSE; 6138e3fc8c0SJed Brown ierr = PetscOptionsBool("-snes_ls_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);CHKERRQ(ierr); 6148e3fc8c0SJed Brown if (set) { 6158e3fc8c0SJed Brown if (flg) { 6168e3fc8c0SJed Brown snes->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */ 6178e3fc8c0SJed Brown ierr = PetscOptionsReal("-snes_ls_precheck_picard_angle","Maximum angle at which to activate the correction","none",snes->precheck_picard_angle,&snes->precheck_picard_angle,PETSC_NULL);CHKERRQ(ierr); 6188e3fc8c0SJed Brown ierr = SNESLineSearchSetPreCheck(snes,SNESLineSearchPreCheckPicard,&snes->precheck_picard_angle);CHKERRQ(ierr); 6198e3fc8c0SJed Brown } else { 6208e3fc8c0SJed Brown ierr = SNESLineSearchSetPreCheck(snes,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 6218e3fc8c0SJed Brown } 6228e3fc8c0SJed Brown } 6238e3fc8c0SJed Brown 62476b2cf59SMatthew Knepley for(i = 0; i < numberofsetfromoptions; i++) { 62576b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 62676b2cf59SMatthew Knepley } 62776b2cf59SMatthew Knepley 628e7788613SBarry Smith if (snes->ops->setfromoptions) { 629e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 630639f9d9dSBarry Smith } 6315d973c19SBarry Smith 6325d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 6335d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 634b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 6354bbc92c1SBarry Smith 636aa3661deSLisandro Dalcin if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 6371cee3971SBarry Smith 6381cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 639aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 640aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 64185385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 64293993e2dSLois Curfman McInnes 64351e86f29SPeter Brune /* if someone has set the SNES PC type, create it. */ 64451e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 64551e86f29SPeter Brune ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 64651e86f29SPeter Brune if (pcset && (!snes->pc)) { 64751e86f29SPeter Brune ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr); 64851e86f29SPeter Brune } 6494a0c5b0cSMatthew G Knepley if (snes->pc) { 650fde0ff24SPeter Brune ierr = SNESSetOptionsPrefix(snes->pc, optionsprefix);CHKERRQ(ierr); 651fde0ff24SPeter Brune ierr = SNESAppendOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr); 6524a0c5b0cSMatthew G Knepley ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 6534a0c5b0cSMatthew G Knepley ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 6544a0c5b0cSMatthew G Knepley } 6553a40ed3dSBarry Smith PetscFunctionReturn(0); 6569b94acceSBarry Smith } 6579b94acceSBarry Smith 658d25893d9SBarry Smith #undef __FUNCT__ 659d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 660d25893d9SBarry Smith /*@ 661d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 662d25893d9SBarry Smith the nonlinear solvers. 663d25893d9SBarry Smith 664d25893d9SBarry Smith Logically Collective on SNES 665d25893d9SBarry Smith 666d25893d9SBarry Smith Input Parameters: 667d25893d9SBarry Smith + snes - the SNES context 668d25893d9SBarry Smith . compute - function to compute the context 669d25893d9SBarry Smith - destroy - function to destroy the context 670d25893d9SBarry Smith 671d25893d9SBarry Smith Level: intermediate 672d25893d9SBarry Smith 673d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 674d25893d9SBarry Smith 675d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 676d25893d9SBarry Smith @*/ 677d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 678d25893d9SBarry Smith { 679d25893d9SBarry Smith PetscFunctionBegin; 680d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 681d25893d9SBarry Smith snes->ops->usercompute = compute; 682d25893d9SBarry Smith snes->ops->userdestroy = destroy; 683d25893d9SBarry Smith PetscFunctionReturn(0); 684d25893d9SBarry Smith } 685a847f771SSatish Balay 6864a2ae208SSatish Balay #undef __FUNCT__ 6874a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 688b07ff414SBarry Smith /*@ 6899b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 6909b94acceSBarry Smith the nonlinear solvers. 6919b94acceSBarry Smith 6923f9fe445SBarry Smith Logically Collective on SNES 693fee21e36SBarry Smith 694c7afd0dbSLois Curfman McInnes Input Parameters: 695c7afd0dbSLois Curfman McInnes + snes - the SNES context 696c7afd0dbSLois Curfman McInnes - usrP - optional user context 697c7afd0dbSLois Curfman McInnes 69836851e7fSLois Curfman McInnes Level: intermediate 69936851e7fSLois Curfman McInnes 7009b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 7019b94acceSBarry Smith 702d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext() 7039b94acceSBarry Smith @*/ 7047087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 7059b94acceSBarry Smith { 7061b2093e4SBarry Smith PetscErrorCode ierr; 707b07ff414SBarry Smith KSP ksp; 7081b2093e4SBarry Smith 7093a40ed3dSBarry Smith PetscFunctionBegin; 7100700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 711b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 712b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 7139b94acceSBarry Smith snes->user = usrP; 7143a40ed3dSBarry Smith PetscFunctionReturn(0); 7159b94acceSBarry Smith } 71674679c65SBarry Smith 7174a2ae208SSatish Balay #undef __FUNCT__ 7184a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 719b07ff414SBarry Smith /*@ 7209b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 7219b94acceSBarry Smith nonlinear solvers. 7229b94acceSBarry Smith 723c7afd0dbSLois Curfman McInnes Not Collective 724c7afd0dbSLois Curfman McInnes 7259b94acceSBarry Smith Input Parameter: 7269b94acceSBarry Smith . snes - SNES context 7279b94acceSBarry Smith 7289b94acceSBarry Smith Output Parameter: 7299b94acceSBarry Smith . usrP - user context 7309b94acceSBarry Smith 73136851e7fSLois Curfman McInnes Level: intermediate 73236851e7fSLois Curfman McInnes 7339b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 7349b94acceSBarry Smith 7359b94acceSBarry Smith .seealso: SNESSetApplicationContext() 7369b94acceSBarry Smith @*/ 737e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 7389b94acceSBarry Smith { 7393a40ed3dSBarry Smith PetscFunctionBegin; 7400700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 741e71120c6SJed Brown *(void**)usrP = snes->user; 7423a40ed3dSBarry Smith PetscFunctionReturn(0); 7439b94acceSBarry Smith } 74474679c65SBarry Smith 7454a2ae208SSatish Balay #undef __FUNCT__ 7464a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 7479b94acceSBarry Smith /*@ 748c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 749c8228a4eSBarry Smith at this time. 7509b94acceSBarry Smith 751c7afd0dbSLois Curfman McInnes Not Collective 752c7afd0dbSLois Curfman McInnes 7539b94acceSBarry Smith Input Parameter: 7549b94acceSBarry Smith . snes - SNES context 7559b94acceSBarry Smith 7569b94acceSBarry Smith Output Parameter: 7579b94acceSBarry Smith . iter - iteration number 7589b94acceSBarry Smith 759c8228a4eSBarry Smith Notes: 760c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 761c8228a4eSBarry Smith 762c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 76308405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 76408405cd6SLois Curfman McInnes .vb 76508405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 76608405cd6SLois Curfman McInnes if (!(it % 2)) { 76708405cd6SLois Curfman McInnes [compute Jacobian here] 76808405cd6SLois Curfman McInnes } 76908405cd6SLois Curfman McInnes .ve 770c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 77108405cd6SLois Curfman McInnes recomputed every second SNES iteration. 772c8228a4eSBarry Smith 77336851e7fSLois Curfman McInnes Level: intermediate 77436851e7fSLois Curfman McInnes 7752b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 7762b668275SBarry Smith 777b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 7789b94acceSBarry Smith @*/ 7797087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 7809b94acceSBarry Smith { 7813a40ed3dSBarry Smith PetscFunctionBegin; 7820700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7834482741eSBarry Smith PetscValidIntPointer(iter,2); 7849b94acceSBarry Smith *iter = snes->iter; 7853a40ed3dSBarry Smith PetscFunctionReturn(0); 7869b94acceSBarry Smith } 78774679c65SBarry Smith 7884a2ae208SSatish Balay #undef __FUNCT__ 789360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber" 790360c497dSPeter Brune /*@ 791360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 792360c497dSPeter Brune 793360c497dSPeter Brune Not Collective 794360c497dSPeter Brune 795360c497dSPeter Brune Input Parameter: 796360c497dSPeter Brune . snes - SNES context 797360c497dSPeter Brune . iter - iteration number 798360c497dSPeter Brune 799360c497dSPeter Brune Level: developer 800360c497dSPeter Brune 801360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number, 802360c497dSPeter Brune 803360c497dSPeter Brune .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 804360c497dSPeter Brune @*/ 805360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 806360c497dSPeter Brune { 807360c497dSPeter Brune PetscErrorCode ierr; 808360c497dSPeter Brune 809360c497dSPeter Brune PetscFunctionBegin; 810360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 811360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 812360c497dSPeter Brune snes->iter = iter; 813360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 814360c497dSPeter Brune PetscFunctionReturn(0); 815360c497dSPeter Brune } 816360c497dSPeter Brune 817360c497dSPeter Brune #undef __FUNCT__ 8184a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 8199b94acceSBarry Smith /*@ 8209b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 8219b94acceSBarry Smith with SNESSSetFunction(). 8229b94acceSBarry Smith 823c7afd0dbSLois Curfman McInnes Collective on SNES 824c7afd0dbSLois Curfman McInnes 8259b94acceSBarry Smith Input Parameter: 8269b94acceSBarry Smith . snes - SNES context 8279b94acceSBarry Smith 8289b94acceSBarry Smith Output Parameter: 8299b94acceSBarry Smith . fnorm - 2-norm of function 8309b94acceSBarry Smith 83136851e7fSLois Curfman McInnes Level: intermediate 83236851e7fSLois Curfman McInnes 8339b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 834a86d99e1SLois Curfman McInnes 835b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 8369b94acceSBarry Smith @*/ 8377087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 8389b94acceSBarry Smith { 8393a40ed3dSBarry Smith PetscFunctionBegin; 8400700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8414482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 8429b94acceSBarry Smith *fnorm = snes->norm; 8433a40ed3dSBarry Smith PetscFunctionReturn(0); 8449b94acceSBarry Smith } 84574679c65SBarry Smith 846360c497dSPeter Brune 847360c497dSPeter Brune #undef __FUNCT__ 848360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm" 849360c497dSPeter Brune /*@ 850360c497dSPeter Brune SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm(). 851360c497dSPeter Brune 852360c497dSPeter Brune Collective on SNES 853360c497dSPeter Brune 854360c497dSPeter Brune Input Parameter: 855360c497dSPeter Brune . snes - SNES context 856360c497dSPeter Brune . fnorm - 2-norm of function 857360c497dSPeter Brune 858360c497dSPeter Brune Level: developer 859360c497dSPeter Brune 860360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm 861360c497dSPeter Brune 862360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm(). 863360c497dSPeter Brune @*/ 864360c497dSPeter Brune PetscErrorCode SNESSetFunctionNorm(SNES snes,PetscReal fnorm) 865360c497dSPeter Brune { 866360c497dSPeter Brune 867360c497dSPeter Brune PetscErrorCode ierr; 868360c497dSPeter Brune 869360c497dSPeter Brune PetscFunctionBegin; 870360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 871360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 872360c497dSPeter Brune snes->norm = fnorm; 873360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 874360c497dSPeter Brune PetscFunctionReturn(0); 875360c497dSPeter Brune } 876360c497dSPeter Brune 8774a2ae208SSatish Balay #undef __FUNCT__ 878b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 8799b94acceSBarry Smith /*@ 880b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 8819b94acceSBarry Smith attempted by the nonlinear solver. 8829b94acceSBarry Smith 883c7afd0dbSLois Curfman McInnes Not Collective 884c7afd0dbSLois Curfman McInnes 8859b94acceSBarry Smith Input Parameter: 8869b94acceSBarry Smith . snes - SNES context 8879b94acceSBarry Smith 8889b94acceSBarry Smith Output Parameter: 8899b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 8909b94acceSBarry Smith 891c96a6f78SLois Curfman McInnes Notes: 892c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 893c96a6f78SLois Curfman McInnes 89436851e7fSLois Curfman McInnes Level: intermediate 89536851e7fSLois Curfman McInnes 8969b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 89758ebbce7SBarry Smith 898e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 89958ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 9009b94acceSBarry Smith @*/ 9017087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 9029b94acceSBarry Smith { 9033a40ed3dSBarry Smith PetscFunctionBegin; 9040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9054482741eSBarry Smith PetscValidIntPointer(nfails,2); 90650ffb88aSMatthew Knepley *nfails = snes->numFailures; 90750ffb88aSMatthew Knepley PetscFunctionReturn(0); 90850ffb88aSMatthew Knepley } 90950ffb88aSMatthew Knepley 91050ffb88aSMatthew Knepley #undef __FUNCT__ 911b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 91250ffb88aSMatthew Knepley /*@ 913b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 91450ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 91550ffb88aSMatthew Knepley 91650ffb88aSMatthew Knepley Not Collective 91750ffb88aSMatthew Knepley 91850ffb88aSMatthew Knepley Input Parameters: 91950ffb88aSMatthew Knepley + snes - SNES context 92050ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 92150ffb88aSMatthew Knepley 92250ffb88aSMatthew Knepley Level: intermediate 92350ffb88aSMatthew Knepley 92450ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 92558ebbce7SBarry Smith 926e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 92758ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 92850ffb88aSMatthew Knepley @*/ 9297087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 93050ffb88aSMatthew Knepley { 93150ffb88aSMatthew Knepley PetscFunctionBegin; 9320700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 93350ffb88aSMatthew Knepley snes->maxFailures = maxFails; 93450ffb88aSMatthew Knepley PetscFunctionReturn(0); 93550ffb88aSMatthew Knepley } 93650ffb88aSMatthew Knepley 93750ffb88aSMatthew Knepley #undef __FUNCT__ 938b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 93950ffb88aSMatthew Knepley /*@ 940b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 94150ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 94250ffb88aSMatthew Knepley 94350ffb88aSMatthew Knepley Not Collective 94450ffb88aSMatthew Knepley 94550ffb88aSMatthew Knepley Input Parameter: 94650ffb88aSMatthew Knepley . snes - SNES context 94750ffb88aSMatthew Knepley 94850ffb88aSMatthew Knepley Output Parameter: 94950ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 95050ffb88aSMatthew Knepley 95150ffb88aSMatthew Knepley Level: intermediate 95250ffb88aSMatthew Knepley 95350ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 95458ebbce7SBarry Smith 955e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 95658ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 95758ebbce7SBarry Smith 95850ffb88aSMatthew Knepley @*/ 9597087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 96050ffb88aSMatthew Knepley { 96150ffb88aSMatthew Knepley PetscFunctionBegin; 9620700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9634482741eSBarry Smith PetscValidIntPointer(maxFails,2); 96450ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 9653a40ed3dSBarry Smith PetscFunctionReturn(0); 9669b94acceSBarry Smith } 967a847f771SSatish Balay 9684a2ae208SSatish Balay #undef __FUNCT__ 9692541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 9702541af92SBarry Smith /*@ 9712541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 9722541af92SBarry Smith done by SNES. 9732541af92SBarry Smith 9742541af92SBarry Smith Not Collective 9752541af92SBarry Smith 9762541af92SBarry Smith Input Parameter: 9772541af92SBarry Smith . snes - SNES context 9782541af92SBarry Smith 9792541af92SBarry Smith Output Parameter: 9802541af92SBarry Smith . nfuncs - number of evaluations 9812541af92SBarry Smith 9822541af92SBarry Smith Level: intermediate 9832541af92SBarry Smith 9842541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 98558ebbce7SBarry Smith 986e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 9872541af92SBarry Smith @*/ 9887087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 9892541af92SBarry Smith { 9902541af92SBarry Smith PetscFunctionBegin; 9910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9922541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 9932541af92SBarry Smith *nfuncs = snes->nfuncs; 9942541af92SBarry Smith PetscFunctionReturn(0); 9952541af92SBarry Smith } 9962541af92SBarry Smith 9972541af92SBarry Smith #undef __FUNCT__ 9983d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 9993d4c4710SBarry Smith /*@ 10003d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 10013d4c4710SBarry Smith linear solvers. 10023d4c4710SBarry Smith 10033d4c4710SBarry Smith Not Collective 10043d4c4710SBarry Smith 10053d4c4710SBarry Smith Input Parameter: 10063d4c4710SBarry Smith . snes - SNES context 10073d4c4710SBarry Smith 10083d4c4710SBarry Smith Output Parameter: 10093d4c4710SBarry Smith . nfails - number of failed solves 10103d4c4710SBarry Smith 10113d4c4710SBarry Smith Notes: 10123d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 10133d4c4710SBarry Smith 10143d4c4710SBarry Smith Level: intermediate 10153d4c4710SBarry Smith 10163d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 101758ebbce7SBarry Smith 1018e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 10193d4c4710SBarry Smith @*/ 10207087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 10213d4c4710SBarry Smith { 10223d4c4710SBarry Smith PetscFunctionBegin; 10230700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10243d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 10253d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 10263d4c4710SBarry Smith PetscFunctionReturn(0); 10273d4c4710SBarry Smith } 10283d4c4710SBarry Smith 10293d4c4710SBarry Smith #undef __FUNCT__ 10303d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 10313d4c4710SBarry Smith /*@ 10323d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 10333d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 10343d4c4710SBarry Smith 10353f9fe445SBarry Smith Logically Collective on SNES 10363d4c4710SBarry Smith 10373d4c4710SBarry Smith Input Parameters: 10383d4c4710SBarry Smith + snes - SNES context 10393d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 10403d4c4710SBarry Smith 10413d4c4710SBarry Smith Level: intermediate 10423d4c4710SBarry Smith 1043a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 10443d4c4710SBarry Smith 10453d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 10463d4c4710SBarry Smith 104758ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 10483d4c4710SBarry Smith @*/ 10497087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 10503d4c4710SBarry Smith { 10513d4c4710SBarry Smith PetscFunctionBegin; 10520700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1053c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 10543d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 10553d4c4710SBarry Smith PetscFunctionReturn(0); 10563d4c4710SBarry Smith } 10573d4c4710SBarry Smith 10583d4c4710SBarry Smith #undef __FUNCT__ 10593d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 10603d4c4710SBarry Smith /*@ 10613d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 10623d4c4710SBarry Smith are allowed before SNES terminates 10633d4c4710SBarry Smith 10643d4c4710SBarry Smith Not Collective 10653d4c4710SBarry Smith 10663d4c4710SBarry Smith Input Parameter: 10673d4c4710SBarry Smith . snes - SNES context 10683d4c4710SBarry Smith 10693d4c4710SBarry Smith Output Parameter: 10703d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 10713d4c4710SBarry Smith 10723d4c4710SBarry Smith Level: intermediate 10733d4c4710SBarry Smith 10743d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 10753d4c4710SBarry Smith 10763d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 10773d4c4710SBarry Smith 1078e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 10793d4c4710SBarry Smith @*/ 10807087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 10813d4c4710SBarry Smith { 10823d4c4710SBarry Smith PetscFunctionBegin; 10830700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10843d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 10853d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 10863d4c4710SBarry Smith PetscFunctionReturn(0); 10873d4c4710SBarry Smith } 10883d4c4710SBarry Smith 10893d4c4710SBarry Smith #undef __FUNCT__ 1090b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 1091c96a6f78SLois Curfman McInnes /*@ 1092b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1093c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1094c96a6f78SLois Curfman McInnes 1095c7afd0dbSLois Curfman McInnes Not Collective 1096c7afd0dbSLois Curfman McInnes 1097c96a6f78SLois Curfman McInnes Input Parameter: 1098c96a6f78SLois Curfman McInnes . snes - SNES context 1099c96a6f78SLois Curfman McInnes 1100c96a6f78SLois Curfman McInnes Output Parameter: 1101c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1102c96a6f78SLois Curfman McInnes 1103c96a6f78SLois Curfman McInnes Notes: 1104c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1105c96a6f78SLois Curfman McInnes 110636851e7fSLois Curfman McInnes Level: intermediate 110736851e7fSLois Curfman McInnes 1108c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 11092b668275SBarry Smith 11108c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 1111c96a6f78SLois Curfman McInnes @*/ 11127087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 1113c96a6f78SLois Curfman McInnes { 11143a40ed3dSBarry Smith PetscFunctionBegin; 11150700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11164482741eSBarry Smith PetscValidIntPointer(lits,2); 1117c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 11183a40ed3dSBarry Smith PetscFunctionReturn(0); 1119c96a6f78SLois Curfman McInnes } 1120c96a6f78SLois Curfman McInnes 11214a2ae208SSatish Balay #undef __FUNCT__ 112294b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 112352baeb72SSatish Balay /*@ 112494b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 11259b94acceSBarry Smith 112694b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 1127c7afd0dbSLois Curfman McInnes 11289b94acceSBarry Smith Input Parameter: 11299b94acceSBarry Smith . snes - the SNES context 11309b94acceSBarry Smith 11319b94acceSBarry Smith Output Parameter: 113294b7f48cSBarry Smith . ksp - the KSP context 11339b94acceSBarry Smith 11349b94acceSBarry Smith Notes: 113594b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 11369b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 11372999313aSBarry Smith PC contexts as well. 11389b94acceSBarry Smith 113936851e7fSLois Curfman McInnes Level: beginner 114036851e7fSLois Curfman McInnes 114194b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 11429b94acceSBarry Smith 11432999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 11449b94acceSBarry Smith @*/ 11457087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 11469b94acceSBarry Smith { 11471cee3971SBarry Smith PetscErrorCode ierr; 11481cee3971SBarry Smith 11493a40ed3dSBarry Smith PetscFunctionBegin; 11500700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11514482741eSBarry Smith PetscValidPointer(ksp,2); 11521cee3971SBarry Smith 11531cee3971SBarry Smith if (!snes->ksp) { 11541cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 11551cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 11561cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 11571cee3971SBarry Smith } 115894b7f48cSBarry Smith *ksp = snes->ksp; 11593a40ed3dSBarry Smith PetscFunctionReturn(0); 11609b94acceSBarry Smith } 116182bf6240SBarry Smith 11624a2ae208SSatish Balay #undef __FUNCT__ 11632999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 11642999313aSBarry Smith /*@ 11652999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 11662999313aSBarry Smith 11672999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 11682999313aSBarry Smith 11692999313aSBarry Smith Input Parameters: 11702999313aSBarry Smith + snes - the SNES context 11712999313aSBarry Smith - ksp - the KSP context 11722999313aSBarry Smith 11732999313aSBarry Smith Notes: 11742999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 11752999313aSBarry Smith so this routine is rarely needed. 11762999313aSBarry Smith 11772999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 11782999313aSBarry Smith decreased by one. 11792999313aSBarry Smith 11802999313aSBarry Smith Level: developer 11812999313aSBarry Smith 11822999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 11832999313aSBarry Smith 11842999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 11852999313aSBarry Smith @*/ 11867087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 11872999313aSBarry Smith { 11882999313aSBarry Smith PetscErrorCode ierr; 11892999313aSBarry Smith 11902999313aSBarry Smith PetscFunctionBegin; 11910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11920700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 11932999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 11947dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1195906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 11962999313aSBarry Smith snes->ksp = ksp; 11972999313aSBarry Smith PetscFunctionReturn(0); 11982999313aSBarry Smith } 11992999313aSBarry Smith 12007adad957SLisandro Dalcin #if 0 12012999313aSBarry Smith #undef __FUNCT__ 12024a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 12036849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1204e24b481bSBarry Smith { 1205e24b481bSBarry Smith PetscFunctionBegin; 1206e24b481bSBarry Smith PetscFunctionReturn(0); 1207e24b481bSBarry Smith } 12087adad957SLisandro Dalcin #endif 1209e24b481bSBarry Smith 12109b94acceSBarry Smith /* -----------------------------------------------------------*/ 12114a2ae208SSatish Balay #undef __FUNCT__ 12124a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 121352baeb72SSatish Balay /*@ 12149b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 12159b94acceSBarry Smith 1216c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1217c7afd0dbSLois Curfman McInnes 1218c7afd0dbSLois Curfman McInnes Input Parameters: 1219906ed7ccSBarry Smith . comm - MPI communicator 12209b94acceSBarry Smith 12219b94acceSBarry Smith Output Parameter: 12229b94acceSBarry Smith . outsnes - the new SNES context 12239b94acceSBarry Smith 1224c7afd0dbSLois Curfman McInnes Options Database Keys: 1225c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1226c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1227c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1228c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1229c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1230c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1231c1f60f51SBarry Smith 123236851e7fSLois Curfman McInnes Level: beginner 123336851e7fSLois Curfman McInnes 12349b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 12359b94acceSBarry Smith 1236a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1237a8054027SBarry Smith 12389b94acceSBarry Smith @*/ 12397087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 12409b94acceSBarry Smith { 1241dfbe8321SBarry Smith PetscErrorCode ierr; 12429b94acceSBarry Smith SNES snes; 1243fa9f3622SBarry Smith SNESKSPEW *kctx; 124437fcc0dbSBarry Smith 12453a40ed3dSBarry Smith PetscFunctionBegin; 1246ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 12478ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 12488ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 12498ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 12508ba1e511SMatthew Knepley #endif 12518ba1e511SMatthew Knepley 12523194b578SJed Brown ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 12537adad957SLisandro Dalcin 125485385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 12552c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 12569b94acceSBarry Smith snes->max_its = 50; 12579750a799SBarry Smith snes->max_funcs = 10000; 12589b94acceSBarry Smith snes->norm = 0.0; 1259b4874afaSBarry Smith snes->rtol = 1.e-8; 1260b4874afaSBarry Smith snes->ttol = 0.0; 126170441072SBarry Smith snes->abstol = 1.e-50; 12629b94acceSBarry Smith snes->xtol = 1.e-8; 12634b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 12649b94acceSBarry Smith snes->nfuncs = 0; 126550ffb88aSMatthew Knepley snes->numFailures = 0; 126650ffb88aSMatthew Knepley snes->maxFailures = 1; 12677a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1268e35cf81dSBarry Smith snes->lagjacobian = 1; 1269a8054027SBarry Smith snes->lagpreconditioner = 1; 1270639f9d9dSBarry Smith snes->numbermonitors = 0; 12719b94acceSBarry Smith snes->data = 0; 12724dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1273186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 12746f24a144SLois Curfman McInnes snes->nwork = 0; 127558c9b817SLisandro Dalcin snes->work = 0; 127658c9b817SLisandro Dalcin snes->nvwork = 0; 127758c9b817SLisandro Dalcin snes->vwork = 0; 1278758f92a0SBarry Smith snes->conv_hist_len = 0; 1279758f92a0SBarry Smith snes->conv_hist_max = 0; 1280758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1281758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1282758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1283184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 128489b92e6fSPeter Brune snes->gssweeps = 1; 12859b94acceSBarry Smith 1286ea630c6eSPeter Brune /* initialize the line search options */ 1287ea630c6eSPeter Brune snes->ls_type = SNES_LS_BASIC; 1288af60355fSPeter Brune snes->ls_its = 1; 1289ea630c6eSPeter Brune snes->damping = 1.0; 1290ea630c6eSPeter Brune snes->maxstep = 1e8; 1291ea630c6eSPeter Brune snes->steptol = 1e-12; 1292ea630c6eSPeter Brune snes->ls_alpha = 1e-4; 1293ea630c6eSPeter Brune snes->ls_monitor = PETSC_NULL; 1294ea630c6eSPeter Brune 1295ea630c6eSPeter Brune snes->ops->linesearch = PETSC_NULL; 1296ea630c6eSPeter Brune snes->precheck = PETSC_NULL; 1297ea630c6eSPeter Brune snes->ops->precheckstep = PETSC_NULL; 1298ea630c6eSPeter Brune snes->postcheck = PETSC_NULL; 1299ea630c6eSPeter Brune snes->ops->postcheckstep= PETSC_NULL; 1300ea630c6eSPeter Brune 13013d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 13023d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 13033d4c4710SBarry Smith 13049b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 130538f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 13069b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 13079b94acceSBarry Smith kctx->version = 2; 13089b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 13099b94acceSBarry Smith this was too large for some test cases */ 131075567043SBarry Smith kctx->rtol_last = 0.0; 13119b94acceSBarry Smith kctx->rtol_max = .9; 13129b94acceSBarry Smith kctx->gamma = 1.0; 131362d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 131471f87433Sdalcinl kctx->alpha2 = kctx->alpha; 13159b94acceSBarry Smith kctx->threshold = .1; 131675567043SBarry Smith kctx->lresid_last = 0.0; 131775567043SBarry Smith kctx->norm_last = 0.0; 13189b94acceSBarry Smith 13199b94acceSBarry Smith *outsnes = snes; 13203a40ed3dSBarry Smith PetscFunctionReturn(0); 13219b94acceSBarry Smith } 13229b94acceSBarry Smith 13234a2ae208SSatish Balay #undef __FUNCT__ 13244a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 13259b94acceSBarry Smith /*@C 13269b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 13279b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 13289b94acceSBarry Smith equations. 13299b94acceSBarry Smith 13303f9fe445SBarry Smith Logically Collective on SNES 1331fee21e36SBarry Smith 1332c7afd0dbSLois Curfman McInnes Input Parameters: 1333c7afd0dbSLois Curfman McInnes + snes - the SNES context 1334c7afd0dbSLois Curfman McInnes . r - vector to store function value 1335de044059SHong Zhang . func - function evaluation routine 1336c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1337c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 13389b94acceSBarry Smith 1339c7afd0dbSLois Curfman McInnes Calling sequence of func: 13408d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1341c7afd0dbSLois Curfman McInnes 1342313e4042SLois Curfman McInnes . f - function vector 1343c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 13449b94acceSBarry Smith 13459b94acceSBarry Smith Notes: 13469b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 13479b94acceSBarry Smith $ f'(x) x = -f(x), 1348c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 13499b94acceSBarry Smith 135036851e7fSLois Curfman McInnes Level: beginner 135136851e7fSLois Curfman McInnes 13529b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 13539b94acceSBarry Smith 13548b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard() 13559b94acceSBarry Smith @*/ 13567087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 13579b94acceSBarry Smith { 135885385478SLisandro Dalcin PetscErrorCode ierr; 13596cab3a1bSJed Brown DM dm; 13606cab3a1bSJed Brown 13613a40ed3dSBarry Smith PetscFunctionBegin; 13620700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1363d2a683ecSLisandro Dalcin if (r) { 1364d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1365d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 136685385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 13676bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 136885385478SLisandro Dalcin snes->vec_func = r; 1369d2a683ecSLisandro Dalcin } else if (!snes->vec_func && snes->dm) { 1370d2a683ecSLisandro Dalcin ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 1371d2a683ecSLisandro Dalcin } 13726cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 13736cab3a1bSJed Brown ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr); 13743a40ed3dSBarry Smith PetscFunctionReturn(0); 13759b94acceSBarry Smith } 13769b94acceSBarry Smith 1377646217ecSPeter Brune 1378646217ecSPeter Brune #undef __FUNCT__ 1379646217ecSPeter Brune #define __FUNCT__ "SNESSetGS" 1380c79ef259SPeter Brune /*@C 1381c79ef259SPeter Brune SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for 1382c79ef259SPeter Brune use with composed nonlinear solvers. 1383c79ef259SPeter Brune 1384c79ef259SPeter Brune Input Parameters: 1385c79ef259SPeter Brune + snes - the SNES context 1386c79ef259SPeter Brune . gsfunc - function evaluation routine 1387c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 1388c79ef259SPeter Brune smoother evaluation routine (may be PETSC_NULL) 1389c79ef259SPeter Brune 1390c79ef259SPeter Brune Calling sequence of func: 1391c79ef259SPeter Brune $ func (SNES snes,Vec x,Vec b,void *ctx); 1392c79ef259SPeter Brune 1393c79ef259SPeter Brune + X - solution vector 1394c79ef259SPeter Brune . B - RHS vector 1395d28543b3SPeter Brune - ctx - optional user-defined Gauss-Seidel context 1396c79ef259SPeter Brune 1397c79ef259SPeter Brune Notes: 1398c79ef259SPeter Brune The GS routines are used by the composed nonlinear solver to generate 1399c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1400c79ef259SPeter Brune 1401d28543b3SPeter Brune Level: intermediate 1402c79ef259SPeter Brune 1403d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1404c79ef259SPeter Brune 1405c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS() 1406c79ef259SPeter Brune @*/ 14076cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx) 14086cab3a1bSJed Brown { 14096cab3a1bSJed Brown PetscErrorCode ierr; 14106cab3a1bSJed Brown DM dm; 14116cab3a1bSJed Brown 1412646217ecSPeter Brune PetscFunctionBegin; 14136cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14146cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 14156cab3a1bSJed Brown ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr); 1416646217ecSPeter Brune PetscFunctionReturn(0); 1417646217ecSPeter Brune } 1418646217ecSPeter Brune 1419d25893d9SBarry Smith #undef __FUNCT__ 142089b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps" 142189b92e6fSPeter Brune /*@ 142289b92e6fSPeter Brune SNESSetGSSweeps - Sets the number of sweeps of GS to use. 142389b92e6fSPeter Brune 142489b92e6fSPeter Brune Input Parameters: 142589b92e6fSPeter Brune + snes - the SNES context 142689b92e6fSPeter Brune - sweeps - the number of sweeps of GS to perform. 142789b92e6fSPeter Brune 142889b92e6fSPeter Brune Level: intermediate 142989b92e6fSPeter Brune 143089b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 143189b92e6fSPeter Brune 143289b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps() 143389b92e6fSPeter Brune @*/ 143489b92e6fSPeter Brune 143589b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) { 143689b92e6fSPeter Brune PetscFunctionBegin; 143789b92e6fSPeter Brune snes->gssweeps = sweeps; 143889b92e6fSPeter Brune PetscFunctionReturn(0); 143989b92e6fSPeter Brune } 144089b92e6fSPeter Brune 144189b92e6fSPeter Brune 144289b92e6fSPeter Brune #undef __FUNCT__ 144389b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps" 144489b92e6fSPeter Brune /*@ 144589b92e6fSPeter Brune SNESGetGSSweeps - Gets the number of sweeps GS will use. 144689b92e6fSPeter Brune 144789b92e6fSPeter Brune Input Parameters: 144889b92e6fSPeter Brune . snes - the SNES context 144989b92e6fSPeter Brune 145089b92e6fSPeter Brune Output Parameters: 145189b92e6fSPeter Brune . sweeps - the number of sweeps of GS to perform. 145289b92e6fSPeter Brune 145389b92e6fSPeter Brune Level: intermediate 145489b92e6fSPeter Brune 145589b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 145689b92e6fSPeter Brune 145789b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps() 145889b92e6fSPeter Brune @*/ 145989b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) { 146089b92e6fSPeter Brune PetscFunctionBegin; 146189b92e6fSPeter Brune *sweeps = snes->gssweeps; 146289b92e6fSPeter Brune PetscFunctionReturn(0); 146389b92e6fSPeter Brune } 146489b92e6fSPeter Brune 146589b92e6fSPeter Brune #undef __FUNCT__ 14668b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 14678b0a5094SBarry Smith PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 14688b0a5094SBarry Smith { 14698b0a5094SBarry Smith PetscErrorCode ierr; 14706cab3a1bSJed Brown void *functx,*jacctx; 14716cab3a1bSJed Brown 14728b0a5094SBarry Smith PetscFunctionBegin; 14736cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 14746cab3a1bSJed Brown ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr); 14758b0a5094SBarry Smith /* A(x)*x - b(x) */ 14766cab3a1bSJed Brown ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr); 14776cab3a1bSJed Brown ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr); 14788b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 14798b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 14808b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 14818b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 14828b0a5094SBarry Smith PetscFunctionReturn(0); 14838b0a5094SBarry Smith } 14848b0a5094SBarry Smith 14858b0a5094SBarry Smith #undef __FUNCT__ 14868b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 14878b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 14888b0a5094SBarry Smith { 14898b0a5094SBarry Smith PetscFunctionBegin; 14908b0a5094SBarry Smith *flag = snes->matstruct; 14918b0a5094SBarry Smith PetscFunctionReturn(0); 14928b0a5094SBarry Smith } 14938b0a5094SBarry Smith 14948b0a5094SBarry Smith #undef __FUNCT__ 14958b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 14968b0a5094SBarry Smith /*@C 14970d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 14988b0a5094SBarry Smith 14998b0a5094SBarry Smith Logically Collective on SNES 15008b0a5094SBarry Smith 15018b0a5094SBarry Smith Input Parameters: 15028b0a5094SBarry Smith + snes - the SNES context 15038b0a5094SBarry Smith . r - vector to store function value 15048b0a5094SBarry Smith . func - function evaluation routine 15058b0a5094SBarry 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) 15068b0a5094SBarry Smith . mat - matrix to store A 15078b0a5094SBarry Smith . mfunc - function to compute matrix value 15088b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 15098b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 15108b0a5094SBarry Smith 15118b0a5094SBarry Smith Calling sequence of func: 15128b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 15138b0a5094SBarry Smith 15148b0a5094SBarry Smith + f - function vector 15158b0a5094SBarry Smith - ctx - optional user-defined function context 15168b0a5094SBarry Smith 15178b0a5094SBarry Smith Calling sequence of mfunc: 15188b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 15198b0a5094SBarry Smith 15208b0a5094SBarry Smith + x - input vector 15218b0a5094SBarry 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(), 15228b0a5094SBarry Smith normally just pass mat in this location 15238b0a5094SBarry Smith . mat - form A(x) matrix 15248b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 15258b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 15268b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 15278b0a5094SBarry Smith 15288b0a5094SBarry Smith Notes: 15298b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 15308b0a5094SBarry Smith 15318b0a5094SBarry 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} 15328b0a5094SBarry 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. 15338b0a5094SBarry Smith 15348b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 15358b0a5094SBarry Smith 15360d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 15370d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 15388b0a5094SBarry Smith 15398b0a5094SBarry 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 15408b0a5094SBarry 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 15418b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 15428b0a5094SBarry Smith 15438b0a5094SBarry Smith Level: beginner 15448b0a5094SBarry Smith 15458b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 15468b0a5094SBarry Smith 15470d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard() 15488b0a5094SBarry Smith @*/ 15498b0a5094SBarry 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) 15508b0a5094SBarry Smith { 15518b0a5094SBarry Smith PetscErrorCode ierr; 15528b0a5094SBarry Smith PetscFunctionBegin; 15538b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15548b0a5094SBarry Smith snes->ops->computepfunction = func; 15558b0a5094SBarry Smith snes->ops->computepjacobian = mfunc; 15568b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 15578b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 15588b0a5094SBarry Smith PetscFunctionReturn(0); 15598b0a5094SBarry Smith } 15608b0a5094SBarry Smith 15618b0a5094SBarry Smith #undef __FUNCT__ 1562d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1563d25893d9SBarry Smith /*@C 1564d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1565d25893d9SBarry Smith 1566d25893d9SBarry Smith Logically Collective on SNES 1567d25893d9SBarry Smith 1568d25893d9SBarry Smith Input Parameters: 1569d25893d9SBarry Smith + snes - the SNES context 1570d25893d9SBarry Smith . func - function evaluation routine 1571d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1572d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1573d25893d9SBarry Smith 1574d25893d9SBarry Smith Calling sequence of func: 1575d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1576d25893d9SBarry Smith 1577d25893d9SBarry Smith . f - function vector 1578d25893d9SBarry Smith - ctx - optional user-defined function context 1579d25893d9SBarry Smith 1580d25893d9SBarry Smith Level: intermediate 1581d25893d9SBarry Smith 1582d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1583d25893d9SBarry Smith 1584d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1585d25893d9SBarry Smith @*/ 1586d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1587d25893d9SBarry Smith { 1588d25893d9SBarry Smith PetscFunctionBegin; 1589d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1590d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1591d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1592d25893d9SBarry Smith PetscFunctionReturn(0); 1593d25893d9SBarry Smith } 1594d25893d9SBarry Smith 15953ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 15963ab0aad5SBarry Smith #undef __FUNCT__ 15971096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 15981096aae1SMatthew Knepley /*@C 15991096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 16001096aae1SMatthew Knepley it assumes a zero right hand side. 16011096aae1SMatthew Knepley 16023f9fe445SBarry Smith Logically Collective on SNES 16031096aae1SMatthew Knepley 16041096aae1SMatthew Knepley Input Parameter: 16051096aae1SMatthew Knepley . snes - the SNES context 16061096aae1SMatthew Knepley 16071096aae1SMatthew Knepley Output Parameter: 1608bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 16091096aae1SMatthew Knepley 16101096aae1SMatthew Knepley Level: intermediate 16111096aae1SMatthew Knepley 16121096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 16131096aae1SMatthew Knepley 161485385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 16151096aae1SMatthew Knepley @*/ 16167087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 16171096aae1SMatthew Knepley { 16181096aae1SMatthew Knepley PetscFunctionBegin; 16190700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16201096aae1SMatthew Knepley PetscValidPointer(rhs,2); 162185385478SLisandro Dalcin *rhs = snes->vec_rhs; 16221096aae1SMatthew Knepley PetscFunctionReturn(0); 16231096aae1SMatthew Knepley } 16241096aae1SMatthew Knepley 16251096aae1SMatthew Knepley #undef __FUNCT__ 16264a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 16279b94acceSBarry Smith /*@ 162836851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 16299b94acceSBarry Smith SNESSetFunction(). 16309b94acceSBarry Smith 1631c7afd0dbSLois Curfman McInnes Collective on SNES 1632c7afd0dbSLois Curfman McInnes 16339b94acceSBarry Smith Input Parameters: 1634c7afd0dbSLois Curfman McInnes + snes - the SNES context 1635c7afd0dbSLois Curfman McInnes - x - input vector 16369b94acceSBarry Smith 16379b94acceSBarry Smith Output Parameter: 16383638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 16399b94acceSBarry Smith 16401bffabb2SLois Curfman McInnes Notes: 164136851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 164236851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 164336851e7fSLois Curfman McInnes themselves. 164436851e7fSLois Curfman McInnes 164536851e7fSLois Curfman McInnes Level: developer 164636851e7fSLois Curfman McInnes 16479b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 16489b94acceSBarry Smith 1649a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 16509b94acceSBarry Smith @*/ 16517087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 16529b94acceSBarry Smith { 1653dfbe8321SBarry Smith PetscErrorCode ierr; 16546cab3a1bSJed Brown DM dm; 16556cab3a1bSJed Brown SNESDM sdm; 16569b94acceSBarry Smith 16573a40ed3dSBarry Smith PetscFunctionBegin; 16580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16590700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 16600700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1661c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1662c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 16634ec14c9cSBarry Smith VecValidValues(x,2,PETSC_TRUE); 1664184914b5SBarry Smith 16656cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 16666cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 1667d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 16686cab3a1bSJed Brown if (sdm->computefunction) { 1669d64ed03dSBarry Smith PetscStackPush("SNES user function"); 16706cab3a1bSJed Brown ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 1671d64ed03dSBarry Smith PetscStackPop; 167273250ac0SBarry Smith } else if (snes->dm) { 1673644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1674c90fad12SPeter Brune } else if (snes->vec_rhs) { 1675c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1676644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 167785385478SLisandro Dalcin if (snes->vec_rhs) { 167885385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 16793ab0aad5SBarry Smith } 1680ae3c334cSLois Curfman McInnes snes->nfuncs++; 1681d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 16824ec14c9cSBarry Smith VecValidValues(y,3,PETSC_FALSE); 16833a40ed3dSBarry Smith PetscFunctionReturn(0); 16849b94acceSBarry Smith } 16859b94acceSBarry Smith 16864a2ae208SSatish Balay #undef __FUNCT__ 1687646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1688c79ef259SPeter Brune /*@ 1689c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1690c79ef259SPeter Brune SNESSetGS(). 1691c79ef259SPeter Brune 1692c79ef259SPeter Brune Collective on SNES 1693c79ef259SPeter Brune 1694c79ef259SPeter Brune Input Parameters: 1695c79ef259SPeter Brune + snes - the SNES context 1696c79ef259SPeter Brune . x - input vector 1697c79ef259SPeter Brune - b - rhs vector 1698c79ef259SPeter Brune 1699c79ef259SPeter Brune Output Parameter: 1700c79ef259SPeter Brune . x - new solution vector 1701c79ef259SPeter Brune 1702c79ef259SPeter Brune Notes: 1703c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1704c79ef259SPeter Brune implementations, so most users would not generally call this routine 1705c79ef259SPeter Brune themselves. 1706c79ef259SPeter Brune 1707c79ef259SPeter Brune Level: developer 1708c79ef259SPeter Brune 1709c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1710c79ef259SPeter Brune 1711c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1712c79ef259SPeter Brune @*/ 1713646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1714646217ecSPeter Brune { 1715646217ecSPeter Brune PetscErrorCode ierr; 171689b92e6fSPeter Brune PetscInt i; 17176cab3a1bSJed Brown DM dm; 17186cab3a1bSJed Brown SNESDM sdm; 1719646217ecSPeter Brune 1720646217ecSPeter Brune PetscFunctionBegin; 1721646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1722646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1723646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1724646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 1725646217ecSPeter Brune if(b) PetscCheckSameComm(snes,1,b,3); 17264ec14c9cSBarry Smith if (b) VecValidValues(b,2,PETSC_TRUE); 1727701cf23dSPeter Brune ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 17286cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 17296cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 17306cab3a1bSJed Brown if (sdm->computegs) { 173189b92e6fSPeter Brune for (i = 0; i < snes->gssweeps; i++) { 1732646217ecSPeter Brune PetscStackPush("SNES user GS"); 17336cab3a1bSJed Brown ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 1734646217ecSPeter Brune PetscStackPop; 173589b92e6fSPeter Brune } 1736646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 1737701cf23dSPeter Brune ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 17384ec14c9cSBarry Smith VecValidValues(x,3,PETSC_FALSE); 1739646217ecSPeter Brune PetscFunctionReturn(0); 1740646217ecSPeter Brune } 1741646217ecSPeter Brune 1742646217ecSPeter Brune 1743646217ecSPeter Brune #undef __FUNCT__ 17444a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 174562fef451SLois Curfman McInnes /*@ 174662fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 174762fef451SLois Curfman McInnes set with SNESSetJacobian(). 174862fef451SLois Curfman McInnes 1749c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1750c7afd0dbSLois Curfman McInnes 175162fef451SLois Curfman McInnes Input Parameters: 1752c7afd0dbSLois Curfman McInnes + snes - the SNES context 1753c7afd0dbSLois Curfman McInnes - x - input vector 175462fef451SLois Curfman McInnes 175562fef451SLois Curfman McInnes Output Parameters: 1756c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 175762fef451SLois Curfman McInnes . B - optional preconditioning matrix 17582b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1759fee21e36SBarry Smith 1760e35cf81dSBarry Smith Options Database Keys: 1761e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1762693365a8SJed Brown . -snes_lag_jacobian <lag> 1763693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1764693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1765693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 17664c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1767c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 1768c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 1769c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 1770c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 1771c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 17724c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 1773c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 1774c01495d3SJed Brown 1775e35cf81dSBarry Smith 177662fef451SLois Curfman McInnes Notes: 177762fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 177862fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 177962fef451SLois Curfman McInnes 178094b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1781dc5a77f8SLois Curfman McInnes flag parameter. 178262fef451SLois Curfman McInnes 178336851e7fSLois Curfman McInnes Level: developer 178436851e7fSLois Curfman McInnes 178562fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 178662fef451SLois Curfman McInnes 1787e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 178862fef451SLois Curfman McInnes @*/ 17897087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 17909b94acceSBarry Smith { 1791dfbe8321SBarry Smith PetscErrorCode ierr; 1792ace3abfcSBarry Smith PetscBool flag; 17936cab3a1bSJed Brown DM dm; 17946cab3a1bSJed Brown SNESDM sdm; 17953a40ed3dSBarry Smith 17963a40ed3dSBarry Smith PetscFunctionBegin; 17970700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 17980700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 17994482741eSBarry Smith PetscValidPointer(flg,5); 1800c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 18014ec14c9cSBarry Smith VecValidValues(X,2,PETSC_TRUE); 18026cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18036cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 18046cab3a1bSJed Brown if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 1805ebd3b9afSBarry Smith 1806ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1807ebd3b9afSBarry Smith 1808fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 1809fe3ffe1eSBarry Smith snes->lagjacobian = -1; 1810fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1811fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 1812e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1813e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1814ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1815ebd3b9afSBarry Smith if (flag) { 1816ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1817ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1818ebd3b9afSBarry Smith } 1819e35cf81dSBarry Smith PetscFunctionReturn(0); 1820e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1821e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1822e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1823ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1824ebd3b9afSBarry Smith if (flag) { 1825ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1826ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1827ebd3b9afSBarry Smith } 1828e35cf81dSBarry Smith PetscFunctionReturn(0); 1829e35cf81dSBarry Smith } 1830e35cf81dSBarry Smith 1831c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 1832e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1833d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 18346cab3a1bSJed Brown ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr); 1835d64ed03dSBarry Smith PetscStackPop; 1836d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1837a8054027SBarry Smith 18383b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 18393b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 18403b4f5425SBarry Smith snes->lagpreconditioner = -1; 18413b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 1842a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1843a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 1844a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 1845a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1846a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 1847a8054027SBarry Smith } 1848a8054027SBarry Smith 18496d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 18500700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 18510700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 1852693365a8SJed Brown { 1853693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 1854693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 1855693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 1856693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 1857693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 1858693365a8SJed Brown if (flag || flag_draw || flag_contour) { 1859693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 1860693365a8SJed Brown MatStructure mstruct; 1861693365a8SJed Brown PetscViewer vdraw,vstdout; 18626b3a5b13SJed Brown PetscBool flg; 1863693365a8SJed Brown if (flag_operator) { 1864693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 1865693365a8SJed Brown Bexp = Bexp_mine; 1866693365a8SJed Brown } else { 1867693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 1868693365a8SJed Brown ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 1869693365a8SJed Brown if (flg) Bexp = *B; 1870693365a8SJed Brown else { 1871693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 1872693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 1873693365a8SJed Brown Bexp = Bexp_mine; 1874693365a8SJed Brown } 1875693365a8SJed Brown } 1876693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 1877693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 1878693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 1879693365a8SJed Brown if (flag_draw || flag_contour) { 1880693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 1881693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 1882693365a8SJed Brown } else vdraw = PETSC_NULL; 1883693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 1884693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 1885693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 1886693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 1887693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1888693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 1889693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1890693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 1891693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1892693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 1893693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 1894693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 1895693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 1896693365a8SJed Brown } 1897693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 1898693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 1899693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 1900693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 1901693365a8SJed Brown } 1902693365a8SJed Brown } 19034c30e9fbSJed Brown { 19046719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 19056719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 19064c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 19076719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 19084c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 19094c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 19106719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 19116719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 19126719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 19136719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 19144c30e9fbSJed Brown Mat Bfd; 19154c30e9fbSJed Brown MatStructure mstruct; 19164c30e9fbSJed Brown PetscViewer vdraw,vstdout; 19174c30e9fbSJed Brown ISColoring iscoloring; 19184c30e9fbSJed Brown MatFDColoring matfdcoloring; 19194c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 19204c30e9fbSJed Brown void *funcctx; 19216719d8e4SJed Brown PetscReal norm1,norm2,normmax; 19224c30e9fbSJed Brown 19234c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 19244c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 19254c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 19264c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 19274c30e9fbSJed Brown 19284c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 19294c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 19304c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 19314c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 19324c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 19334c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 19344c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 19354c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 19364c30e9fbSJed Brown 19374c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 19384c30e9fbSJed Brown if (flag_draw || flag_contour) { 19394c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 19404c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 19414c30e9fbSJed Brown } else vdraw = PETSC_NULL; 19424c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 19436719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 19444c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 19454c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 19466719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 19474c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 19484c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 19494c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 19506719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 19514c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 19526719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 19536719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 19544c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 19554c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 19564c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 19574c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 19584c30e9fbSJed Brown } 19594c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 19606719d8e4SJed Brown 19616719d8e4SJed Brown if (flag_threshold) { 19626719d8e4SJed Brown PetscInt bs,rstart,rend,i; 19636719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 19646719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 19656719d8e4SJed Brown for (i=rstart; i<rend; i++) { 19666719d8e4SJed Brown const PetscScalar *ba,*ca; 19676719d8e4SJed Brown const PetscInt *bj,*cj; 19686719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 19696719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 19706719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 19716719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 19726719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 19736719d8e4SJed Brown for (j=0; j<bn; j++) { 19746719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 19756719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 19766719d8e4SJed Brown maxentrycol = bj[j]; 19776719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 19786719d8e4SJed Brown } 19796719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 19806719d8e4SJed Brown maxdiffcol = bj[j]; 19816719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 19826719d8e4SJed Brown } 19836719d8e4SJed Brown if (rdiff > maxrdiff) { 19846719d8e4SJed Brown maxrdiffcol = bj[j]; 19856719d8e4SJed Brown maxrdiff = rdiff; 19866719d8e4SJed Brown } 19876719d8e4SJed Brown } 19886719d8e4SJed Brown if (maxrdiff > 1) { 19896719d8e4SJed 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); 19906719d8e4SJed Brown for (j=0; j<bn; j++) { 19916719d8e4SJed Brown PetscReal rdiff; 19926719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 19936719d8e4SJed Brown if (rdiff > 1) { 19946719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 19956719d8e4SJed Brown } 19966719d8e4SJed Brown } 19976719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 19986719d8e4SJed Brown } 19996719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 20006719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 20016719d8e4SJed Brown } 20026719d8e4SJed Brown } 20034c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 20044c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 20054c30e9fbSJed Brown } 20064c30e9fbSJed Brown } 20073a40ed3dSBarry Smith PetscFunctionReturn(0); 20089b94acceSBarry Smith } 20099b94acceSBarry Smith 20104a2ae208SSatish Balay #undef __FUNCT__ 20114a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 20129b94acceSBarry Smith /*@C 20139b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2014044dda88SLois Curfman McInnes location to store the matrix. 20159b94acceSBarry Smith 20163f9fe445SBarry Smith Logically Collective on SNES and Mat 2017c7afd0dbSLois Curfman McInnes 20189b94acceSBarry Smith Input Parameters: 2019c7afd0dbSLois Curfman McInnes + snes - the SNES context 20209b94acceSBarry Smith . A - Jacobian matrix 20219b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 2022efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 2023c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 2024efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 20259b94acceSBarry Smith 20269b94acceSBarry Smith Calling sequence of func: 20278d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 20289b94acceSBarry Smith 2029c7afd0dbSLois Curfman McInnes + x - input vector 20309b94acceSBarry Smith . A - Jacobian matrix 20319b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 2032ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 20332b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 2034c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 20359b94acceSBarry Smith 20369b94acceSBarry Smith Notes: 203794b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 20382cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 2039ac21db08SLois Curfman McInnes 2040ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 20419b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 20429b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 20439b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 20449b94acceSBarry Smith throughout the global iterations. 20459b94acceSBarry Smith 204616913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 204716913363SBarry Smith each matrix. 204816913363SBarry Smith 2049a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 2050a8a26c1eSJed Brown must be a MatFDColoring. 2051a8a26c1eSJed Brown 2052c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2053c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2054c3cc8fd1SJed Brown 205536851e7fSLois Curfman McInnes Level: beginner 205636851e7fSLois Curfman McInnes 20579b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 20589b94acceSBarry Smith 20593ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 20609b94acceSBarry Smith @*/ 20617087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 20629b94acceSBarry Smith { 2063dfbe8321SBarry Smith PetscErrorCode ierr; 20646cab3a1bSJed Brown DM dm; 20653a7fca6bSBarry Smith 20663a40ed3dSBarry Smith PetscFunctionBegin; 20670700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 20680700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 20690700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 2070c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 207106975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 20726cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 20736cab3a1bSJed Brown ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr); 20743a7fca6bSBarry Smith if (A) { 20757dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 20766bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 20779b94acceSBarry Smith snes->jacobian = A; 20783a7fca6bSBarry Smith } 20793a7fca6bSBarry Smith if (B) { 20807dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 20816bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 20829b94acceSBarry Smith snes->jacobian_pre = B; 20833a7fca6bSBarry Smith } 20843a40ed3dSBarry Smith PetscFunctionReturn(0); 20859b94acceSBarry Smith } 208662fef451SLois Curfman McInnes 20874a2ae208SSatish Balay #undef __FUNCT__ 20884a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 2089c2aafc4cSSatish Balay /*@C 2090b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2091b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2092b4fd4287SBarry Smith 2093c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2094c7afd0dbSLois Curfman McInnes 2095b4fd4287SBarry Smith Input Parameter: 2096b4fd4287SBarry Smith . snes - the nonlinear solver context 2097b4fd4287SBarry Smith 2098b4fd4287SBarry Smith Output Parameters: 2099c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 2100b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 210170e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 210270e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 2103fee21e36SBarry Smith 210436851e7fSLois Curfman McInnes Level: advanced 210536851e7fSLois Curfman McInnes 2106b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 2107b4fd4287SBarry Smith @*/ 21087087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 2109b4fd4287SBarry Smith { 21106cab3a1bSJed Brown PetscErrorCode ierr; 21116cab3a1bSJed Brown DM dm; 21126cab3a1bSJed Brown SNESDM sdm; 21136cab3a1bSJed Brown 21143a40ed3dSBarry Smith PetscFunctionBegin; 21150700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2116b4fd4287SBarry Smith if (A) *A = snes->jacobian; 2117b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 21186cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 21196cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 21206cab3a1bSJed Brown if (func) *func = sdm->computejacobian; 21216cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 21223a40ed3dSBarry Smith PetscFunctionReturn(0); 2123b4fd4287SBarry Smith } 2124b4fd4287SBarry Smith 21259b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 21269b94acceSBarry Smith 21274a2ae208SSatish Balay #undef __FUNCT__ 21284a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 21299b94acceSBarry Smith /*@ 21309b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2131272ac6f2SLois Curfman McInnes of a nonlinear solver. 21329b94acceSBarry Smith 2133fee21e36SBarry Smith Collective on SNES 2134fee21e36SBarry Smith 2135c7afd0dbSLois Curfman McInnes Input Parameters: 213670e92668SMatthew Knepley . snes - the SNES context 2137c7afd0dbSLois Curfman McInnes 2138272ac6f2SLois Curfman McInnes Notes: 2139272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2140272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2141272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2142272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2143272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2144272ac6f2SLois Curfman McInnes 214536851e7fSLois Curfman McInnes Level: advanced 214636851e7fSLois Curfman McInnes 21479b94acceSBarry Smith .keywords: SNES, nonlinear, setup 21489b94acceSBarry Smith 21499b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 21509b94acceSBarry Smith @*/ 21517087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 21529b94acceSBarry Smith { 2153dfbe8321SBarry Smith PetscErrorCode ierr; 21546cab3a1bSJed Brown DM dm; 21556cab3a1bSJed Brown SNESDM sdm; 21563a40ed3dSBarry Smith 21573a40ed3dSBarry Smith PetscFunctionBegin; 21580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 21594dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 21609b94acceSBarry Smith 21617adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 216285385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 216385385478SLisandro Dalcin } 216485385478SLisandro Dalcin 2165a63bb30eSJed Brown ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 216617186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 216758c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 216858c9b817SLisandro Dalcin 216958c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 217058c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 217158c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 217258c9b817SLisandro Dalcin } 217358c9b817SLisandro Dalcin 21746cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 21756cab3a1bSJed Brown ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */ 21766cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 21776cab3a1bSJed Brown if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc"); 21786cab3a1bSJed Brown if (!snes->vec_func) { 21796cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2180214df951SJed Brown } 2181efd51863SBarry Smith 2182b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 2183b710008aSBarry Smith 2184d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 2185d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2186d25893d9SBarry Smith } 2187d25893d9SBarry Smith 2188410397dcSLisandro Dalcin if (snes->ops->setup) { 2189410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2190410397dcSLisandro Dalcin } 219158c9b817SLisandro Dalcin 21927aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 21933a40ed3dSBarry Smith PetscFunctionReturn(0); 21949b94acceSBarry Smith } 21959b94acceSBarry Smith 21964a2ae208SSatish Balay #undef __FUNCT__ 219737596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 219837596af1SLisandro Dalcin /*@ 219937596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 220037596af1SLisandro Dalcin 220137596af1SLisandro Dalcin Collective on SNES 220237596af1SLisandro Dalcin 220337596af1SLisandro Dalcin Input Parameter: 220437596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 220537596af1SLisandro Dalcin 2206d25893d9SBarry Smith Level: intermediate 2207d25893d9SBarry Smith 2208d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 220937596af1SLisandro Dalcin 221037596af1SLisandro Dalcin .keywords: SNES, destroy 221137596af1SLisandro Dalcin 221237596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 221337596af1SLisandro Dalcin @*/ 221437596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 221537596af1SLisandro Dalcin { 221637596af1SLisandro Dalcin PetscErrorCode ierr; 221737596af1SLisandro Dalcin 221837596af1SLisandro Dalcin PetscFunctionBegin; 221937596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2220d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2221d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2222d25893d9SBarry Smith snes->user = PETSC_NULL; 2223d25893d9SBarry Smith } 22248a23116dSBarry Smith if (snes->pc) { 22258a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 22268a23116dSBarry Smith } 22278a23116dSBarry Smith 222837596af1SLisandro Dalcin if (snes->ops->reset) { 222937596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 223037596af1SLisandro Dalcin } 223137596af1SLisandro Dalcin if (snes->ksp) {ierr = KSPReset(snes->ksp);CHKERRQ(ierr);} 22326bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 22336bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 22346bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 22356bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 22366bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 22376bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2238c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2239c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 224037596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 224137596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 224237596af1SLisandro Dalcin PetscFunctionReturn(0); 224337596af1SLisandro Dalcin } 224437596af1SLisandro Dalcin 224537596af1SLisandro Dalcin #undef __FUNCT__ 22464a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 224752baeb72SSatish Balay /*@ 22489b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 22499b94acceSBarry Smith with SNESCreate(). 22509b94acceSBarry Smith 2251c7afd0dbSLois Curfman McInnes Collective on SNES 2252c7afd0dbSLois Curfman McInnes 22539b94acceSBarry Smith Input Parameter: 22549b94acceSBarry Smith . snes - the SNES context 22559b94acceSBarry Smith 225636851e7fSLois Curfman McInnes Level: beginner 225736851e7fSLois Curfman McInnes 22589b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 22599b94acceSBarry Smith 226063a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 22619b94acceSBarry Smith @*/ 22626bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 22639b94acceSBarry Smith { 22646849ba73SBarry Smith PetscErrorCode ierr; 22653a40ed3dSBarry Smith 22663a40ed3dSBarry Smith PetscFunctionBegin; 22676bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 22686bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 22696bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2270d4bb536fSBarry Smith 22716bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 22728a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 22736b8b9a38SLisandro Dalcin 2274be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 22756bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 22766bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 22776d4c513bSLisandro Dalcin 22786bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 22796bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 22806b8b9a38SLisandro Dalcin 22816bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 22826bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 22836bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 22846b8b9a38SLisandro Dalcin } 22856bf464f9SBarry Smith if ((*snes)->conv_malloc) { 22866bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 22876bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 228858c9b817SLisandro Dalcin } 2289ea630c6eSPeter Brune ierr = PetscViewerDestroy(&(*snes)->ls_monitor);CHKERRQ(ierr); 22906bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2291a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 22923a40ed3dSBarry Smith PetscFunctionReturn(0); 22939b94acceSBarry Smith } 22949b94acceSBarry Smith 22959b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 22969b94acceSBarry Smith 22974a2ae208SSatish Balay #undef __FUNCT__ 2298a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2299a8054027SBarry Smith /*@ 2300a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2301a8054027SBarry Smith 23023f9fe445SBarry Smith Logically Collective on SNES 2303a8054027SBarry Smith 2304a8054027SBarry Smith Input Parameters: 2305a8054027SBarry Smith + snes - the SNES context 2306a8054027SBarry 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 23073b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2308a8054027SBarry Smith 2309a8054027SBarry Smith Options Database Keys: 2310a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2311a8054027SBarry Smith 2312a8054027SBarry Smith Notes: 2313a8054027SBarry Smith The default is 1 2314a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2315a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2316a8054027SBarry Smith 2317a8054027SBarry Smith Level: intermediate 2318a8054027SBarry Smith 2319a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2320a8054027SBarry Smith 2321e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2322a8054027SBarry Smith 2323a8054027SBarry Smith @*/ 23247087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2325a8054027SBarry Smith { 2326a8054027SBarry Smith PetscFunctionBegin; 23270700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2328e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2329e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2330c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2331a8054027SBarry Smith snes->lagpreconditioner = lag; 2332a8054027SBarry Smith PetscFunctionReturn(0); 2333a8054027SBarry Smith } 2334a8054027SBarry Smith 2335a8054027SBarry Smith #undef __FUNCT__ 2336efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2337efd51863SBarry Smith /*@ 2338efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2339efd51863SBarry Smith 2340efd51863SBarry Smith Logically Collective on SNES 2341efd51863SBarry Smith 2342efd51863SBarry Smith Input Parameters: 2343efd51863SBarry Smith + snes - the SNES context 2344efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2345efd51863SBarry Smith 2346efd51863SBarry Smith Options Database Keys: 2347efd51863SBarry Smith . -snes_grid_sequence <steps> 2348efd51863SBarry Smith 2349efd51863SBarry Smith Level: intermediate 2350efd51863SBarry Smith 2351c0df2a02SJed Brown Notes: 2352c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2353c0df2a02SJed Brown 2354efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2355efd51863SBarry Smith 2356efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2357efd51863SBarry Smith 2358efd51863SBarry Smith @*/ 2359efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2360efd51863SBarry Smith { 2361efd51863SBarry Smith PetscFunctionBegin; 2362efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2363efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2364efd51863SBarry Smith snes->gridsequence = steps; 2365efd51863SBarry Smith PetscFunctionReturn(0); 2366efd51863SBarry Smith } 2367efd51863SBarry Smith 2368efd51863SBarry Smith #undef __FUNCT__ 2369a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2370a8054027SBarry Smith /*@ 2371a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2372a8054027SBarry Smith 23733f9fe445SBarry Smith Not Collective 2374a8054027SBarry Smith 2375a8054027SBarry Smith Input Parameter: 2376a8054027SBarry Smith . snes - the SNES context 2377a8054027SBarry Smith 2378a8054027SBarry Smith Output Parameter: 2379a8054027SBarry 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 23803b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2381a8054027SBarry Smith 2382a8054027SBarry Smith Options Database Keys: 2383a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2384a8054027SBarry Smith 2385a8054027SBarry Smith Notes: 2386a8054027SBarry Smith The default is 1 2387a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2388a8054027SBarry Smith 2389a8054027SBarry Smith Level: intermediate 2390a8054027SBarry Smith 2391a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2392a8054027SBarry Smith 2393a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2394a8054027SBarry Smith 2395a8054027SBarry Smith @*/ 23967087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2397a8054027SBarry Smith { 2398a8054027SBarry Smith PetscFunctionBegin; 23990700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2400a8054027SBarry Smith *lag = snes->lagpreconditioner; 2401a8054027SBarry Smith PetscFunctionReturn(0); 2402a8054027SBarry Smith } 2403a8054027SBarry Smith 2404a8054027SBarry Smith #undef __FUNCT__ 2405e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2406e35cf81dSBarry Smith /*@ 2407e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2408e35cf81dSBarry Smith often the preconditioner is rebuilt. 2409e35cf81dSBarry Smith 24103f9fe445SBarry Smith Logically Collective on SNES 2411e35cf81dSBarry Smith 2412e35cf81dSBarry Smith Input Parameters: 2413e35cf81dSBarry Smith + snes - the SNES context 2414e35cf81dSBarry 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 2415fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2416e35cf81dSBarry Smith 2417e35cf81dSBarry Smith Options Database Keys: 2418e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2419e35cf81dSBarry Smith 2420e35cf81dSBarry Smith Notes: 2421e35cf81dSBarry Smith The default is 1 2422e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2423fe3ffe1eSBarry 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 2424fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2425e35cf81dSBarry Smith 2426e35cf81dSBarry Smith Level: intermediate 2427e35cf81dSBarry Smith 2428e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2429e35cf81dSBarry Smith 2430e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2431e35cf81dSBarry Smith 2432e35cf81dSBarry Smith @*/ 24337087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2434e35cf81dSBarry Smith { 2435e35cf81dSBarry Smith PetscFunctionBegin; 24360700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2437e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2438e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2439c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2440e35cf81dSBarry Smith snes->lagjacobian = lag; 2441e35cf81dSBarry Smith PetscFunctionReturn(0); 2442e35cf81dSBarry Smith } 2443e35cf81dSBarry Smith 2444e35cf81dSBarry Smith #undef __FUNCT__ 2445e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2446e35cf81dSBarry Smith /*@ 2447e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2448e35cf81dSBarry Smith 24493f9fe445SBarry Smith Not Collective 2450e35cf81dSBarry Smith 2451e35cf81dSBarry Smith Input Parameter: 2452e35cf81dSBarry Smith . snes - the SNES context 2453e35cf81dSBarry Smith 2454e35cf81dSBarry Smith Output Parameter: 2455e35cf81dSBarry 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 2456e35cf81dSBarry Smith the Jacobian is built etc. 2457e35cf81dSBarry Smith 2458e35cf81dSBarry Smith Options Database Keys: 2459e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2460e35cf81dSBarry Smith 2461e35cf81dSBarry Smith Notes: 2462e35cf81dSBarry Smith The default is 1 2463e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2464e35cf81dSBarry Smith 2465e35cf81dSBarry Smith Level: intermediate 2466e35cf81dSBarry Smith 2467e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2468e35cf81dSBarry Smith 2469e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2470e35cf81dSBarry Smith 2471e35cf81dSBarry Smith @*/ 24727087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2473e35cf81dSBarry Smith { 2474e35cf81dSBarry Smith PetscFunctionBegin; 24750700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2476e35cf81dSBarry Smith *lag = snes->lagjacobian; 2477e35cf81dSBarry Smith PetscFunctionReturn(0); 2478e35cf81dSBarry Smith } 2479e35cf81dSBarry Smith 2480e35cf81dSBarry Smith #undef __FUNCT__ 24814a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 24829b94acceSBarry Smith /*@ 2483d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 24849b94acceSBarry Smith 24853f9fe445SBarry Smith Logically Collective on SNES 2486c7afd0dbSLois Curfman McInnes 24879b94acceSBarry Smith Input Parameters: 2488c7afd0dbSLois Curfman McInnes + snes - the SNES context 248970441072SBarry Smith . abstol - absolute convergence tolerance 249033174efeSLois Curfman McInnes . rtol - relative convergence tolerance 249133174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 249233174efeSLois Curfman McInnes of the change in the solution between steps 249333174efeSLois Curfman McInnes . maxit - maximum number of iterations 2494c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2495fee21e36SBarry Smith 249633174efeSLois Curfman McInnes Options Database Keys: 249770441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2498c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2499c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2500c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2501c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 25029b94acceSBarry Smith 2503d7a720efSLois Curfman McInnes Notes: 25049b94acceSBarry Smith The default maximum number of iterations is 50. 25059b94acceSBarry Smith The default maximum number of function evaluations is 1000. 25069b94acceSBarry Smith 250736851e7fSLois Curfman McInnes Level: intermediate 250836851e7fSLois Curfman McInnes 250933174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 25109b94acceSBarry Smith 25112492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 25129b94acceSBarry Smith @*/ 25137087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 25149b94acceSBarry Smith { 25153a40ed3dSBarry Smith PetscFunctionBegin; 25160700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2517c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2518c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2519c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2520c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2521c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2522c5eb9154SBarry Smith 2523ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2524ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2525ab54825eSJed Brown snes->abstol = abstol; 2526ab54825eSJed Brown } 2527ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2528ab54825eSJed 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); 2529ab54825eSJed Brown snes->rtol = rtol; 2530ab54825eSJed Brown } 2531ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2532ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2533ab54825eSJed Brown snes->xtol = stol; 2534ab54825eSJed Brown } 2535ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2536ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2537ab54825eSJed Brown snes->max_its = maxit; 2538ab54825eSJed Brown } 2539ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2540ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2541ab54825eSJed Brown snes->max_funcs = maxf; 2542ab54825eSJed Brown } 25433a40ed3dSBarry Smith PetscFunctionReturn(0); 25449b94acceSBarry Smith } 25459b94acceSBarry Smith 25464a2ae208SSatish Balay #undef __FUNCT__ 25474a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 25489b94acceSBarry Smith /*@ 254933174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 255033174efeSLois Curfman McInnes 2551c7afd0dbSLois Curfman McInnes Not Collective 2552c7afd0dbSLois Curfman McInnes 255333174efeSLois Curfman McInnes Input Parameters: 2554c7afd0dbSLois Curfman McInnes + snes - the SNES context 255585385478SLisandro Dalcin . atol - absolute convergence tolerance 255633174efeSLois Curfman McInnes . rtol - relative convergence tolerance 255733174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 255833174efeSLois Curfman McInnes of the change in the solution between steps 255933174efeSLois Curfman McInnes . maxit - maximum number of iterations 2560c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2561fee21e36SBarry Smith 256233174efeSLois Curfman McInnes Notes: 256333174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 256433174efeSLois Curfman McInnes 256536851e7fSLois Curfman McInnes Level: intermediate 256636851e7fSLois Curfman McInnes 256733174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 256833174efeSLois Curfman McInnes 256933174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 257033174efeSLois Curfman McInnes @*/ 25717087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 257233174efeSLois Curfman McInnes { 25733a40ed3dSBarry Smith PetscFunctionBegin; 25740700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 257585385478SLisandro Dalcin if (atol) *atol = snes->abstol; 257633174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 257733174efeSLois Curfman McInnes if (stol) *stol = snes->xtol; 257833174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 257933174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 25803a40ed3dSBarry Smith PetscFunctionReturn(0); 258133174efeSLois Curfman McInnes } 258233174efeSLois Curfman McInnes 25834a2ae208SSatish Balay #undef __FUNCT__ 25844a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 258533174efeSLois Curfman McInnes /*@ 25869b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 25879b94acceSBarry Smith 25883f9fe445SBarry Smith Logically Collective on SNES 2589fee21e36SBarry Smith 2590c7afd0dbSLois Curfman McInnes Input Parameters: 2591c7afd0dbSLois Curfman McInnes + snes - the SNES context 2592c7afd0dbSLois Curfman McInnes - tol - tolerance 2593c7afd0dbSLois Curfman McInnes 25949b94acceSBarry Smith Options Database Key: 2595c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 25969b94acceSBarry Smith 259736851e7fSLois Curfman McInnes Level: intermediate 259836851e7fSLois Curfman McInnes 25999b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 26009b94acceSBarry Smith 26012492ecdbSBarry Smith .seealso: SNESSetTolerances() 26029b94acceSBarry Smith @*/ 26037087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 26049b94acceSBarry Smith { 26053a40ed3dSBarry Smith PetscFunctionBegin; 26060700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2607c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 26089b94acceSBarry Smith snes->deltatol = tol; 26093a40ed3dSBarry Smith PetscFunctionReturn(0); 26109b94acceSBarry Smith } 26119b94acceSBarry Smith 2612df9fa365SBarry Smith /* 2613df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2614df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2615df9fa365SBarry Smith macros instead of functions 2616df9fa365SBarry Smith */ 26174a2ae208SSatish Balay #undef __FUNCT__ 2618a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 26197087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2620ce1608b8SBarry Smith { 2621dfbe8321SBarry Smith PetscErrorCode ierr; 2622ce1608b8SBarry Smith 2623ce1608b8SBarry Smith PetscFunctionBegin; 26240700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2625a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2626ce1608b8SBarry Smith PetscFunctionReturn(0); 2627ce1608b8SBarry Smith } 2628ce1608b8SBarry Smith 26294a2ae208SSatish Balay #undef __FUNCT__ 2630a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 26317087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2632df9fa365SBarry Smith { 2633dfbe8321SBarry Smith PetscErrorCode ierr; 2634df9fa365SBarry Smith 2635df9fa365SBarry Smith PetscFunctionBegin; 2636a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2637df9fa365SBarry Smith PetscFunctionReturn(0); 2638df9fa365SBarry Smith } 2639df9fa365SBarry Smith 26404a2ae208SSatish Balay #undef __FUNCT__ 2641a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 26426bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2643df9fa365SBarry Smith { 2644dfbe8321SBarry Smith PetscErrorCode ierr; 2645df9fa365SBarry Smith 2646df9fa365SBarry Smith PetscFunctionBegin; 2647a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2648df9fa365SBarry Smith PetscFunctionReturn(0); 2649df9fa365SBarry Smith } 2650df9fa365SBarry Smith 26517087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2652b271bb04SBarry Smith #undef __FUNCT__ 2653b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 26547087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2655b271bb04SBarry Smith { 2656b271bb04SBarry Smith PetscDrawLG lg; 2657b271bb04SBarry Smith PetscErrorCode ierr; 2658b271bb04SBarry Smith PetscReal x,y,per; 2659b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2660b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2661b271bb04SBarry Smith PetscDraw draw; 2662b271bb04SBarry Smith PetscFunctionBegin; 2663b271bb04SBarry Smith if (!monctx) { 2664b271bb04SBarry Smith MPI_Comm comm; 2665b271bb04SBarry Smith 2666b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2667b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2668b271bb04SBarry Smith } 2669b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2670b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2671b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2672b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2673b271bb04SBarry Smith x = (PetscReal) n; 2674b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2675b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2676b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2677b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2678b271bb04SBarry Smith } 2679b271bb04SBarry Smith 2680b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2681b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2682b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2683b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2684b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2685b271bb04SBarry Smith x = (PetscReal) n; 2686b271bb04SBarry Smith y = 100.0*per; 2687b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2688b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2689b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2690b271bb04SBarry Smith } 2691b271bb04SBarry Smith 2692b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2693b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2694b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2695b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2696b271bb04SBarry Smith x = (PetscReal) n; 2697b271bb04SBarry Smith y = (prev - rnorm)/prev; 2698b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2699b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2700b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2701b271bb04SBarry Smith } 2702b271bb04SBarry Smith 2703b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2704b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2705b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2706b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2707b271bb04SBarry Smith x = (PetscReal) n; 2708b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2709b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2710b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2711b271bb04SBarry Smith } 2712b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2713b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2714b271bb04SBarry Smith } 2715b271bb04SBarry Smith prev = rnorm; 2716b271bb04SBarry Smith PetscFunctionReturn(0); 2717b271bb04SBarry Smith } 2718b271bb04SBarry Smith 2719b271bb04SBarry Smith #undef __FUNCT__ 2720b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 27217087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2722b271bb04SBarry Smith { 2723b271bb04SBarry Smith PetscErrorCode ierr; 2724b271bb04SBarry Smith 2725b271bb04SBarry Smith PetscFunctionBegin; 2726b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2727b271bb04SBarry Smith PetscFunctionReturn(0); 2728b271bb04SBarry Smith } 2729b271bb04SBarry Smith 2730b271bb04SBarry Smith #undef __FUNCT__ 2731b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 27326bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2733b271bb04SBarry Smith { 2734b271bb04SBarry Smith PetscErrorCode ierr; 2735b271bb04SBarry Smith 2736b271bb04SBarry Smith PetscFunctionBegin; 2737b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2738b271bb04SBarry Smith PetscFunctionReturn(0); 2739b271bb04SBarry Smith } 2740b271bb04SBarry Smith 27417a03ce2fSLisandro Dalcin #undef __FUNCT__ 27427a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 2743228d79bcSJed Brown /*@ 2744228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 2745228d79bcSJed Brown 2746228d79bcSJed Brown Collective on SNES 2747228d79bcSJed Brown 2748228d79bcSJed Brown Input Parameters: 2749228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 2750228d79bcSJed Brown . iter - iteration number 2751228d79bcSJed Brown - rnorm - relative norm of the residual 2752228d79bcSJed Brown 2753228d79bcSJed Brown Notes: 2754228d79bcSJed Brown This routine is called by the SNES implementations. 2755228d79bcSJed Brown It does not typically need to be called by the user. 2756228d79bcSJed Brown 2757228d79bcSJed Brown Level: developer 2758228d79bcSJed Brown 2759228d79bcSJed Brown .seealso: SNESMonitorSet() 2760228d79bcSJed Brown @*/ 27617a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 27627a03ce2fSLisandro Dalcin { 27637a03ce2fSLisandro Dalcin PetscErrorCode ierr; 27647a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 27657a03ce2fSLisandro Dalcin 27667a03ce2fSLisandro Dalcin PetscFunctionBegin; 27677a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 27687a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 27697a03ce2fSLisandro Dalcin } 27707a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 27717a03ce2fSLisandro Dalcin } 27727a03ce2fSLisandro Dalcin 27739b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 27749b94acceSBarry Smith 27754a2ae208SSatish Balay #undef __FUNCT__ 2776a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 27779b94acceSBarry Smith /*@C 2778a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 27799b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 27809b94acceSBarry Smith progress. 27819b94acceSBarry Smith 27823f9fe445SBarry Smith Logically Collective on SNES 2783fee21e36SBarry Smith 2784c7afd0dbSLois Curfman McInnes Input Parameters: 2785c7afd0dbSLois Curfman McInnes + snes - the SNES context 2786c7afd0dbSLois Curfman McInnes . func - monitoring routine 2787b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 2788e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 2789b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 2790b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 27919b94acceSBarry Smith 2792c7afd0dbSLois Curfman McInnes Calling sequence of func: 2793a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2794c7afd0dbSLois Curfman McInnes 2795c7afd0dbSLois Curfman McInnes + snes - the SNES context 2796c7afd0dbSLois Curfman McInnes . its - iteration number 2797c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 279840a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 27999b94acceSBarry Smith 28009665c990SLois Curfman McInnes Options Database Keys: 2801a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 2802a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 2803a6570f20SBarry Smith uses SNESMonitorLGCreate() 2804cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 2805c7afd0dbSLois Curfman McInnes been hardwired into a code by 2806a6570f20SBarry Smith calls to SNESMonitorSet(), but 2807c7afd0dbSLois Curfman McInnes does not cancel those set via 2808c7afd0dbSLois Curfman McInnes the options database. 28099665c990SLois Curfman McInnes 2810639f9d9dSBarry Smith Notes: 28116bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 2812a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 28136bc08f3fSLois Curfman McInnes order in which they were set. 2814639f9d9dSBarry Smith 2815025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 2816025f1a04SBarry Smith 281736851e7fSLois Curfman McInnes Level: intermediate 281836851e7fSLois Curfman McInnes 28199b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 28209b94acceSBarry Smith 2821a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 28229b94acceSBarry Smith @*/ 2823c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 28249b94acceSBarry Smith { 2825b90d0a6eSBarry Smith PetscInt i; 2826649052a6SBarry Smith PetscErrorCode ierr; 2827b90d0a6eSBarry Smith 28283a40ed3dSBarry Smith PetscFunctionBegin; 28290700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 283017186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2831b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 2832649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 2833649052a6SBarry Smith if (monitordestroy) { 2834c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 2835649052a6SBarry Smith } 2836b90d0a6eSBarry Smith PetscFunctionReturn(0); 2837b90d0a6eSBarry Smith } 2838b90d0a6eSBarry Smith } 2839b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 2840b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 2841639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 28423a40ed3dSBarry Smith PetscFunctionReturn(0); 28439b94acceSBarry Smith } 28449b94acceSBarry Smith 28454a2ae208SSatish Balay #undef __FUNCT__ 2846a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 28475cd90555SBarry Smith /*@C 2848a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 28495cd90555SBarry Smith 28503f9fe445SBarry Smith Logically Collective on SNES 2851c7afd0dbSLois Curfman McInnes 28525cd90555SBarry Smith Input Parameters: 28535cd90555SBarry Smith . snes - the SNES context 28545cd90555SBarry Smith 28551a480d89SAdministrator Options Database Key: 2856a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 2857a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 2858c7afd0dbSLois Curfman McInnes set via the options database 28595cd90555SBarry Smith 28605cd90555SBarry Smith Notes: 28615cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 28625cd90555SBarry Smith 286336851e7fSLois Curfman McInnes Level: intermediate 286436851e7fSLois Curfman McInnes 28655cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 28665cd90555SBarry Smith 2867a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 28685cd90555SBarry Smith @*/ 28697087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 28705cd90555SBarry Smith { 2871d952e501SBarry Smith PetscErrorCode ierr; 2872d952e501SBarry Smith PetscInt i; 2873d952e501SBarry Smith 28745cd90555SBarry Smith PetscFunctionBegin; 28750700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2876d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 2877d952e501SBarry Smith if (snes->monitordestroy[i]) { 28783c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 2879d952e501SBarry Smith } 2880d952e501SBarry Smith } 28815cd90555SBarry Smith snes->numbermonitors = 0; 28825cd90555SBarry Smith PetscFunctionReturn(0); 28835cd90555SBarry Smith } 28845cd90555SBarry Smith 28854a2ae208SSatish Balay #undef __FUNCT__ 28864a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 28879b94acceSBarry Smith /*@C 28889b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 28899b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 28909b94acceSBarry Smith 28913f9fe445SBarry Smith Logically Collective on SNES 2892fee21e36SBarry Smith 2893c7afd0dbSLois Curfman McInnes Input Parameters: 2894c7afd0dbSLois Curfman McInnes + snes - the SNES context 2895c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 28967f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 28977f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 28989b94acceSBarry Smith 2899c7afd0dbSLois Curfman McInnes Calling sequence of func: 290006ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 2901c7afd0dbSLois Curfman McInnes 2902c7afd0dbSLois Curfman McInnes + snes - the SNES context 290306ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 2904c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 2905184914b5SBarry Smith . reason - reason for convergence/divergence 2906c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 29074b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 29084b27c08aSLois Curfman McInnes - f - 2-norm of function 29099b94acceSBarry Smith 291036851e7fSLois Curfman McInnes Level: advanced 291136851e7fSLois Curfman McInnes 29129b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 29139b94acceSBarry Smith 291485385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 29159b94acceSBarry Smith @*/ 29167087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 29179b94acceSBarry Smith { 29187f7931b9SBarry Smith PetscErrorCode ierr; 29197f7931b9SBarry Smith 29203a40ed3dSBarry Smith PetscFunctionBegin; 29210700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 292285385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 29237f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 29247f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 29257f7931b9SBarry Smith } 292685385478SLisandro Dalcin snes->ops->converged = func; 29277f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 292885385478SLisandro Dalcin snes->cnvP = cctx; 29293a40ed3dSBarry Smith PetscFunctionReturn(0); 29309b94acceSBarry Smith } 29319b94acceSBarry Smith 29324a2ae208SSatish Balay #undef __FUNCT__ 29334a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 293452baeb72SSatish Balay /*@ 2935184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 2936184914b5SBarry Smith 2937184914b5SBarry Smith Not Collective 2938184914b5SBarry Smith 2939184914b5SBarry Smith Input Parameter: 2940184914b5SBarry Smith . snes - the SNES context 2941184914b5SBarry Smith 2942184914b5SBarry Smith Output Parameter: 29434d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 2944184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 2945184914b5SBarry Smith 2946184914b5SBarry Smith Level: intermediate 2947184914b5SBarry Smith 2948184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 2949184914b5SBarry Smith 2950184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 2951184914b5SBarry Smith 295285385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 2953184914b5SBarry Smith @*/ 29547087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 2955184914b5SBarry Smith { 2956184914b5SBarry Smith PetscFunctionBegin; 29570700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 29584482741eSBarry Smith PetscValidPointer(reason,2); 2959184914b5SBarry Smith *reason = snes->reason; 2960184914b5SBarry Smith PetscFunctionReturn(0); 2961184914b5SBarry Smith } 2962184914b5SBarry Smith 29634a2ae208SSatish Balay #undef __FUNCT__ 29644a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 2965c9005455SLois Curfman McInnes /*@ 2966c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 2967c9005455SLois Curfman McInnes 29683f9fe445SBarry Smith Logically Collective on SNES 2969fee21e36SBarry Smith 2970c7afd0dbSLois Curfman McInnes Input Parameters: 2971c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 29728c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 2973cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 2974758f92a0SBarry Smith . na - size of a and its 297564731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 2976758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 2977c7afd0dbSLois Curfman McInnes 2978308dcc3eSBarry Smith Notes: 2979308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 2980308dcc3eSBarry Smith default array of length 10000 is allocated. 2981308dcc3eSBarry Smith 2982c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 2983c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 2984c9005455SLois Curfman McInnes during the section of code that is being timed. 2985c9005455SLois Curfman McInnes 298636851e7fSLois Curfman McInnes Level: intermediate 298736851e7fSLois Curfman McInnes 2988c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 2989758f92a0SBarry Smith 299008405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 2991758f92a0SBarry Smith 2992c9005455SLois Curfman McInnes @*/ 29937087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 2994c9005455SLois Curfman McInnes { 2995308dcc3eSBarry Smith PetscErrorCode ierr; 2996308dcc3eSBarry Smith 29973a40ed3dSBarry Smith PetscFunctionBegin; 29980700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 29994482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 3000a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 3001308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 3002308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 3003308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 3004308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 3005308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 3006308dcc3eSBarry Smith } 3007c9005455SLois Curfman McInnes snes->conv_hist = a; 3008758f92a0SBarry Smith snes->conv_hist_its = its; 3009758f92a0SBarry Smith snes->conv_hist_max = na; 3010a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 3011758f92a0SBarry Smith snes->conv_hist_reset = reset; 3012758f92a0SBarry Smith PetscFunctionReturn(0); 3013758f92a0SBarry Smith } 3014758f92a0SBarry Smith 3015308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3016c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 3017c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 3018308dcc3eSBarry Smith EXTERN_C_BEGIN 3019308dcc3eSBarry Smith #undef __FUNCT__ 3020308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 3021308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3022308dcc3eSBarry Smith { 3023308dcc3eSBarry Smith mxArray *mat; 3024308dcc3eSBarry Smith PetscInt i; 3025308dcc3eSBarry Smith PetscReal *ar; 3026308dcc3eSBarry Smith 3027308dcc3eSBarry Smith PetscFunctionBegin; 3028308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3029308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3030308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 3031308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 3032308dcc3eSBarry Smith } 3033308dcc3eSBarry Smith PetscFunctionReturn(mat); 3034308dcc3eSBarry Smith } 3035308dcc3eSBarry Smith EXTERN_C_END 3036308dcc3eSBarry Smith #endif 3037308dcc3eSBarry Smith 3038308dcc3eSBarry Smith 30394a2ae208SSatish Balay #undef __FUNCT__ 30404a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 30410c4c9dddSBarry Smith /*@C 3042758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3043758f92a0SBarry Smith 30443f9fe445SBarry Smith Not Collective 3045758f92a0SBarry Smith 3046758f92a0SBarry Smith Input Parameter: 3047758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3048758f92a0SBarry Smith 3049758f92a0SBarry Smith Output Parameters: 3050758f92a0SBarry Smith . a - array to hold history 3051758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3052758f92a0SBarry Smith negative if not converged) for each solve. 3053758f92a0SBarry Smith - na - size of a and its 3054758f92a0SBarry Smith 3055758f92a0SBarry Smith Notes: 3056758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3057758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3058758f92a0SBarry Smith 3059758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3060758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3061758f92a0SBarry Smith during the section of code that is being timed. 3062758f92a0SBarry Smith 3063758f92a0SBarry Smith Level: intermediate 3064758f92a0SBarry Smith 3065758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3066758f92a0SBarry Smith 3067758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3068758f92a0SBarry Smith 3069758f92a0SBarry Smith @*/ 30707087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3071758f92a0SBarry Smith { 3072758f92a0SBarry Smith PetscFunctionBegin; 30730700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3074758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3075758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3076758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 30773a40ed3dSBarry Smith PetscFunctionReturn(0); 3078c9005455SLois Curfman McInnes } 3079c9005455SLois Curfman McInnes 3080e74ef692SMatthew Knepley #undef __FUNCT__ 3081e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 3082ac226902SBarry Smith /*@C 308376b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3084eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 30857e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 308676b2cf59SMatthew Knepley 30873f9fe445SBarry Smith Logically Collective on SNES 308876b2cf59SMatthew Knepley 308976b2cf59SMatthew Knepley Input Parameters: 309076b2cf59SMatthew Knepley . snes - The nonlinear solver context 309176b2cf59SMatthew Knepley . func - The function 309276b2cf59SMatthew Knepley 309376b2cf59SMatthew Knepley Calling sequence of func: 3094b5d30489SBarry Smith . func (SNES snes, PetscInt step); 309576b2cf59SMatthew Knepley 309676b2cf59SMatthew Knepley . step - The current step of the iteration 309776b2cf59SMatthew Knepley 3098fe97e370SBarry Smith Level: advanced 3099fe97e370SBarry Smith 3100fe97e370SBarry 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() 3101fe97e370SBarry Smith This is not used by most users. 310276b2cf59SMatthew Knepley 310376b2cf59SMatthew Knepley .keywords: SNES, update 3104b5d30489SBarry Smith 310585385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 310676b2cf59SMatthew Knepley @*/ 31077087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 310876b2cf59SMatthew Knepley { 310976b2cf59SMatthew Knepley PetscFunctionBegin; 31100700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3111e7788613SBarry Smith snes->ops->update = func; 311276b2cf59SMatthew Knepley PetscFunctionReturn(0); 311376b2cf59SMatthew Knepley } 311476b2cf59SMatthew Knepley 3115e74ef692SMatthew Knepley #undef __FUNCT__ 3116e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 311776b2cf59SMatthew Knepley /*@ 311876b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 311976b2cf59SMatthew Knepley 312076b2cf59SMatthew Knepley Not collective 312176b2cf59SMatthew Knepley 312276b2cf59SMatthew Knepley Input Parameters: 312376b2cf59SMatthew Knepley . snes - The nonlinear solver context 312476b2cf59SMatthew Knepley . step - The current step of the iteration 312576b2cf59SMatthew Knepley 3126205452f4SMatthew Knepley Level: intermediate 3127205452f4SMatthew Knepley 312876b2cf59SMatthew Knepley .keywords: SNES, update 3129a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 313076b2cf59SMatthew Knepley @*/ 31317087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 313276b2cf59SMatthew Knepley { 313376b2cf59SMatthew Knepley PetscFunctionBegin; 313476b2cf59SMatthew Knepley PetscFunctionReturn(0); 313576b2cf59SMatthew Knepley } 313676b2cf59SMatthew Knepley 31374a2ae208SSatish Balay #undef __FUNCT__ 31384a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 31399b94acceSBarry Smith /* 31409b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 31419b94acceSBarry Smith positive parameter delta. 31429b94acceSBarry Smith 31439b94acceSBarry Smith Input Parameters: 3144c7afd0dbSLois Curfman McInnes + snes - the SNES context 31459b94acceSBarry Smith . y - approximate solution of linear system 31469b94acceSBarry Smith . fnorm - 2-norm of current function 3147c7afd0dbSLois Curfman McInnes - delta - trust region size 31489b94acceSBarry Smith 31499b94acceSBarry Smith Output Parameters: 3150c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 31519b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 31529b94acceSBarry Smith region, and exceeds zero otherwise. 3153c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 31549b94acceSBarry Smith 31559b94acceSBarry Smith Note: 31564b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 31579b94acceSBarry Smith is set to be the maximum allowable step size. 31589b94acceSBarry Smith 31599b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 31609b94acceSBarry Smith */ 3161dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 31629b94acceSBarry Smith { 3163064f8208SBarry Smith PetscReal nrm; 3164ea709b57SSatish Balay PetscScalar cnorm; 3165dfbe8321SBarry Smith PetscErrorCode ierr; 31663a40ed3dSBarry Smith 31673a40ed3dSBarry Smith PetscFunctionBegin; 31680700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31690700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3170c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3171184914b5SBarry Smith 3172064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3173064f8208SBarry Smith if (nrm > *delta) { 3174064f8208SBarry Smith nrm = *delta/nrm; 3175064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3176064f8208SBarry Smith cnorm = nrm; 31772dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 31789b94acceSBarry Smith *ynorm = *delta; 31799b94acceSBarry Smith } else { 31809b94acceSBarry Smith *gpnorm = 0.0; 3181064f8208SBarry Smith *ynorm = nrm; 31829b94acceSBarry Smith } 31833a40ed3dSBarry Smith PetscFunctionReturn(0); 31849b94acceSBarry Smith } 31859b94acceSBarry Smith 31864a2ae208SSatish Balay #undef __FUNCT__ 31874a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 31886ce558aeSBarry Smith /*@C 3189f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3190f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 31919b94acceSBarry Smith 3192c7afd0dbSLois Curfman McInnes Collective on SNES 3193c7afd0dbSLois Curfman McInnes 3194b2002411SLois Curfman McInnes Input Parameters: 3195c7afd0dbSLois Curfman McInnes + snes - the SNES context 31963cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 319785385478SLisandro Dalcin - x - the solution vector. 31989b94acceSBarry Smith 3199b2002411SLois Curfman McInnes Notes: 32008ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 32018ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 32028ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 32038ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 32048ddd3da0SLois Curfman McInnes 320536851e7fSLois Curfman McInnes Level: beginner 320636851e7fSLois Curfman McInnes 32079b94acceSBarry Smith .keywords: SNES, nonlinear, solve 32089b94acceSBarry Smith 3209c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 32109b94acceSBarry Smith @*/ 32117087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 32129b94acceSBarry Smith { 3213dfbe8321SBarry Smith PetscErrorCode ierr; 3214ace3abfcSBarry Smith PetscBool flg; 3215eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 3216eabae89aSBarry Smith PetscViewer viewer; 3217efd51863SBarry Smith PetscInt grid; 3218a69afd8bSBarry Smith Vec xcreated = PETSC_NULL; 3219052efed2SBarry Smith 32203a40ed3dSBarry Smith PetscFunctionBegin; 32210700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3222a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3223a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 32240700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 322585385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 322685385478SLisandro Dalcin 3227a69afd8bSBarry Smith if (!x && snes->dm) { 3228a69afd8bSBarry Smith ierr = DMCreateGlobalVector(snes->dm,&xcreated);CHKERRQ(ierr); 3229a69afd8bSBarry Smith x = xcreated; 3230a69afd8bSBarry Smith } 3231a69afd8bSBarry Smith 3232a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3233efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3234efd51863SBarry Smith 323585385478SLisandro Dalcin /* set solution vector */ 3236efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 32376bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 323885385478SLisandro Dalcin snes->vec_sol = x; 323985385478SLisandro Dalcin /* set afine vector if provided */ 324085385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 32416bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 324285385478SLisandro Dalcin snes->vec_rhs = b; 324385385478SLisandro Dalcin 324470e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 32453f149594SLisandro Dalcin 32467eee914bSBarry Smith if (!grid) { 32477eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3248d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3249dd568438SSatish Balay } else if (snes->dm) { 3250dd568438SSatish Balay PetscBool ig; 3251dd568438SSatish Balay ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr); 3252dd568438SSatish Balay if (ig) { 32537eee914bSBarry Smith ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr); 32547eee914bSBarry Smith } 3255d25893d9SBarry Smith } 3256dd568438SSatish Balay } 3257d25893d9SBarry Smith 3258abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 325950ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3260d5e45103SBarry Smith 32613f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 32624936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 326385385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 32644936397dSBarry Smith if (snes->domainerror){ 32654936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 32664936397dSBarry Smith snes->domainerror = PETSC_FALSE; 32674936397dSBarry Smith } 326817186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 32693f149594SLisandro Dalcin 32707adad957SLisandro Dalcin ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 3271eabae89aSBarry Smith if (flg && !PetscPreLoadingOn) { 32727adad957SLisandro Dalcin ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 3273eabae89aSBarry Smith ierr = SNESView(snes,viewer);CHKERRQ(ierr); 32746bf464f9SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3275eabae89aSBarry Smith } 3276eabae89aSBarry Smith 327790d69ab7SBarry Smith flg = PETSC_FALSE; 3278acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3279da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 32805968eb51SBarry Smith if (snes->printreason) { 3281a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 32825968eb51SBarry Smith if (snes->reason > 0) { 3283a8248277SBarry Smith ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 32845968eb51SBarry Smith } else { 3285a8248277SBarry Smith ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 32865968eb51SBarry Smith } 3287a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 32885968eb51SBarry Smith } 32895968eb51SBarry Smith 32908501fc72SJed Brown flg = PETSC_FALSE; 32918501fc72SJed Brown ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 32928501fc72SJed Brown if (flg) { 32938501fc72SJed Brown PetscViewer viewer; 32948501fc72SJed Brown ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 32958501fc72SJed Brown ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 32968501fc72SJed Brown ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 32978501fc72SJed Brown ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 32988501fc72SJed Brown ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 32998501fc72SJed Brown } 33008501fc72SJed Brown 3301e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3302efd51863SBarry Smith if (grid < snes->gridsequence) { 3303efd51863SBarry Smith DM fine; 3304efd51863SBarry Smith Vec xnew; 3305efd51863SBarry Smith Mat interp; 3306efd51863SBarry Smith 3307efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3308e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3309efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3310efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3311efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3312efd51863SBarry Smith x = xnew; 3313efd51863SBarry Smith 3314efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3315efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3316efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3317a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3318efd51863SBarry Smith } 3319efd51863SBarry Smith } 3320a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 33213a40ed3dSBarry Smith PetscFunctionReturn(0); 33229b94acceSBarry Smith } 33239b94acceSBarry Smith 33249b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 33259b94acceSBarry Smith 33264a2ae208SSatish Balay #undef __FUNCT__ 33274a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 332882bf6240SBarry Smith /*@C 33294b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 33309b94acceSBarry Smith 3331fee21e36SBarry Smith Collective on SNES 3332fee21e36SBarry Smith 3333c7afd0dbSLois Curfman McInnes Input Parameters: 3334c7afd0dbSLois Curfman McInnes + snes - the SNES context 3335454a90a3SBarry Smith - type - a known method 3336c7afd0dbSLois Curfman McInnes 3337c7afd0dbSLois Curfman McInnes Options Database Key: 3338454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3339c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3340ae12b187SLois Curfman McInnes 33419b94acceSBarry Smith Notes: 3342e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 33434b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3344c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 33454b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3346c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 33479b94acceSBarry Smith 3348ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3349ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3350ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3351ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3352ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3353ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3354ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3355ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3356ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3357b0a32e0cSBarry Smith appropriate method. 335836851e7fSLois Curfman McInnes 335936851e7fSLois Curfman McInnes Level: intermediate 3360a703fe33SLois Curfman McInnes 3361454a90a3SBarry Smith .keywords: SNES, set, type 3362435da068SBarry Smith 3363435da068SBarry Smith .seealso: SNESType, SNESCreate() 3364435da068SBarry Smith 33659b94acceSBarry Smith @*/ 33667087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 33679b94acceSBarry Smith { 3368dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3369ace3abfcSBarry Smith PetscBool match; 33703a40ed3dSBarry Smith 33713a40ed3dSBarry Smith PetscFunctionBegin; 33720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 33734482741eSBarry Smith PetscValidCharPointer(type,2); 337482bf6240SBarry Smith 33756831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 33760f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 337792ff6ae8SBarry Smith 33784b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3379e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 338075396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 3381b5c23020SJed Brown if (snes->ops->destroy) { 3382b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 3383b5c23020SJed Brown snes->ops->destroy = PETSC_NULL; 3384b5c23020SJed Brown } 338575396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 338675396ef9SLisandro Dalcin snes->ops->setup = 0; 338775396ef9SLisandro Dalcin snes->ops->solve = 0; 338875396ef9SLisandro Dalcin snes->ops->view = 0; 338975396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 339075396ef9SLisandro Dalcin snes->ops->destroy = 0; 339175396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 339275396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3393454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 339403bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 33959fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 33969fb22e1aSBarry Smith if (PetscAMSPublishAll) { 33979fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 33989fb22e1aSBarry Smith } 33999fb22e1aSBarry Smith #endif 34003a40ed3dSBarry Smith PetscFunctionReturn(0); 34019b94acceSBarry Smith } 34029b94acceSBarry Smith 3403a847f771SSatish Balay 34049b94acceSBarry Smith /* --------------------------------------------------------------------- */ 34054a2ae208SSatish Balay #undef __FUNCT__ 34064a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 340752baeb72SSatish Balay /*@ 34089b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3409f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 34109b94acceSBarry Smith 3411fee21e36SBarry Smith Not Collective 3412fee21e36SBarry Smith 341336851e7fSLois Curfman McInnes Level: advanced 341436851e7fSLois Curfman McInnes 34159b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 34169b94acceSBarry Smith 34179b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 34189b94acceSBarry Smith @*/ 34197087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 34209b94acceSBarry Smith { 3421dfbe8321SBarry Smith PetscErrorCode ierr; 342282bf6240SBarry Smith 34233a40ed3dSBarry Smith PetscFunctionBegin; 34241441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 34254c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 34263a40ed3dSBarry Smith PetscFunctionReturn(0); 34279b94acceSBarry Smith } 34289b94acceSBarry Smith 34294a2ae208SSatish Balay #undef __FUNCT__ 34304a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 34319b94acceSBarry Smith /*@C 34329a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 34339b94acceSBarry Smith 3434c7afd0dbSLois Curfman McInnes Not Collective 3435c7afd0dbSLois Curfman McInnes 34369b94acceSBarry Smith Input Parameter: 34374b0e389bSBarry Smith . snes - nonlinear solver context 34389b94acceSBarry Smith 34399b94acceSBarry Smith Output Parameter: 34403a7fca6bSBarry Smith . type - SNES method (a character string) 34419b94acceSBarry Smith 344236851e7fSLois Curfman McInnes Level: intermediate 344336851e7fSLois Curfman McInnes 3444454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 34459b94acceSBarry Smith @*/ 34467087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 34479b94acceSBarry Smith { 34483a40ed3dSBarry Smith PetscFunctionBegin; 34490700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34504482741eSBarry Smith PetscValidPointer(type,2); 34517adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 34523a40ed3dSBarry Smith PetscFunctionReturn(0); 34539b94acceSBarry Smith } 34549b94acceSBarry Smith 34554a2ae208SSatish Balay #undef __FUNCT__ 34564a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 345752baeb72SSatish Balay /*@ 34589b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3459c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 34609b94acceSBarry Smith 3461c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3462c7afd0dbSLois Curfman McInnes 34639b94acceSBarry Smith Input Parameter: 34649b94acceSBarry Smith . snes - the SNES context 34659b94acceSBarry Smith 34669b94acceSBarry Smith Output Parameter: 34679b94acceSBarry Smith . x - the solution 34689b94acceSBarry Smith 346970e92668SMatthew Knepley Level: intermediate 347036851e7fSLois Curfman McInnes 34719b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 34729b94acceSBarry Smith 347385385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 34749b94acceSBarry Smith @*/ 34757087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 34769b94acceSBarry Smith { 34773a40ed3dSBarry Smith PetscFunctionBegin; 34780700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34794482741eSBarry Smith PetscValidPointer(x,2); 348085385478SLisandro Dalcin *x = snes->vec_sol; 348170e92668SMatthew Knepley PetscFunctionReturn(0); 348270e92668SMatthew Knepley } 348370e92668SMatthew Knepley 348470e92668SMatthew Knepley #undef __FUNCT__ 34854a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 348652baeb72SSatish Balay /*@ 34879b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 34889b94acceSBarry Smith stored. 34899b94acceSBarry Smith 3490c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3491c7afd0dbSLois Curfman McInnes 34929b94acceSBarry Smith Input Parameter: 34939b94acceSBarry Smith . snes - the SNES context 34949b94acceSBarry Smith 34959b94acceSBarry Smith Output Parameter: 34969b94acceSBarry Smith . x - the solution update 34979b94acceSBarry Smith 349836851e7fSLois Curfman McInnes Level: advanced 349936851e7fSLois Curfman McInnes 35009b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 35019b94acceSBarry Smith 350285385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 35039b94acceSBarry Smith @*/ 35047087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 35059b94acceSBarry Smith { 35063a40ed3dSBarry Smith PetscFunctionBegin; 35070700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35084482741eSBarry Smith PetscValidPointer(x,2); 350985385478SLisandro Dalcin *x = snes->vec_sol_update; 35103a40ed3dSBarry Smith PetscFunctionReturn(0); 35119b94acceSBarry Smith } 35129b94acceSBarry Smith 35134a2ae208SSatish Balay #undef __FUNCT__ 35144a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 35159b94acceSBarry Smith /*@C 35163638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 35179b94acceSBarry Smith 3518a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 3519c7afd0dbSLois Curfman McInnes 35209b94acceSBarry Smith Input Parameter: 35219b94acceSBarry Smith . snes - the SNES context 35229b94acceSBarry Smith 35239b94acceSBarry Smith Output Parameter: 35247bf4e008SBarry Smith + r - the function (or PETSC_NULL) 352570e92668SMatthew Knepley . func - the function (or PETSC_NULL) 352670e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 35279b94acceSBarry Smith 352836851e7fSLois Curfman McInnes Level: advanced 352936851e7fSLois Curfman McInnes 3530a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 35319b94acceSBarry Smith 35324b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 35339b94acceSBarry Smith @*/ 35347087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 35359b94acceSBarry Smith { 3536a63bb30eSJed Brown PetscErrorCode ierr; 35376cab3a1bSJed Brown DM dm; 3538a63bb30eSJed Brown 35393a40ed3dSBarry Smith PetscFunctionBegin; 35400700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3541a63bb30eSJed Brown if (r) { 3542a63bb30eSJed Brown if (!snes->vec_func) { 3543a63bb30eSJed Brown if (snes->vec_rhs) { 3544a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 3545a63bb30eSJed Brown } else if (snes->vec_sol) { 3546a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 3547a63bb30eSJed Brown } else if (snes->dm) { 3548a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 3549a63bb30eSJed Brown } 3550a63bb30eSJed Brown } 3551a63bb30eSJed Brown *r = snes->vec_func; 3552a63bb30eSJed Brown } 35536cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 35546cab3a1bSJed Brown ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr); 35553a40ed3dSBarry Smith PetscFunctionReturn(0); 35569b94acceSBarry Smith } 35579b94acceSBarry Smith 3558c79ef259SPeter Brune /*@C 3559c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3560c79ef259SPeter Brune 3561c79ef259SPeter Brune Input Parameter: 3562c79ef259SPeter Brune . snes - the SNES context 3563c79ef259SPeter Brune 3564c79ef259SPeter Brune Output Parameter: 3565c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3566c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3567c79ef259SPeter Brune 3568c79ef259SPeter Brune Level: advanced 3569c79ef259SPeter Brune 3570c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3571c79ef259SPeter Brune 3572c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3573c79ef259SPeter Brune @*/ 3574c79ef259SPeter Brune 35754a2ae208SSatish Balay #undef __FUNCT__ 3576646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3577646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3578646217ecSPeter Brune { 35796cab3a1bSJed Brown PetscErrorCode ierr; 35806cab3a1bSJed Brown DM dm; 35816cab3a1bSJed Brown 3582646217ecSPeter Brune PetscFunctionBegin; 3583646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35846cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 35856cab3a1bSJed Brown ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr); 3586646217ecSPeter Brune PetscFunctionReturn(0); 3587646217ecSPeter Brune } 3588646217ecSPeter Brune 35894a2ae208SSatish Balay #undef __FUNCT__ 35904a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 35913c7409f5SSatish Balay /*@C 35923c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3593d850072dSLois Curfman McInnes SNES options in the database. 35943c7409f5SSatish Balay 35953f9fe445SBarry Smith Logically Collective on SNES 3596fee21e36SBarry Smith 3597c7afd0dbSLois Curfman McInnes Input Parameter: 3598c7afd0dbSLois Curfman McInnes + snes - the SNES context 3599c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3600c7afd0dbSLois Curfman McInnes 3601d850072dSLois Curfman McInnes Notes: 3602a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3603c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3604d850072dSLois Curfman McInnes 360536851e7fSLois Curfman McInnes Level: advanced 360636851e7fSLois Curfman McInnes 36073c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3608a86d99e1SLois Curfman McInnes 3609a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 36103c7409f5SSatish Balay @*/ 36117087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 36123c7409f5SSatish Balay { 3613dfbe8321SBarry Smith PetscErrorCode ierr; 36143c7409f5SSatish Balay 36153a40ed3dSBarry Smith PetscFunctionBegin; 36160700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3617639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 36181cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 361994b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 36203a40ed3dSBarry Smith PetscFunctionReturn(0); 36213c7409f5SSatish Balay } 36223c7409f5SSatish Balay 36234a2ae208SSatish Balay #undef __FUNCT__ 36244a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 36253c7409f5SSatish Balay /*@C 3626f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3627d850072dSLois Curfman McInnes SNES options in the database. 36283c7409f5SSatish Balay 36293f9fe445SBarry Smith Logically Collective on SNES 3630fee21e36SBarry Smith 3631c7afd0dbSLois Curfman McInnes Input Parameters: 3632c7afd0dbSLois Curfman McInnes + snes - the SNES context 3633c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3634c7afd0dbSLois Curfman McInnes 3635d850072dSLois Curfman McInnes Notes: 3636a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3637c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3638d850072dSLois Curfman McInnes 363936851e7fSLois Curfman McInnes Level: advanced 364036851e7fSLois Curfman McInnes 36413c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3642a86d99e1SLois Curfman McInnes 3643a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 36443c7409f5SSatish Balay @*/ 36457087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 36463c7409f5SSatish Balay { 3647dfbe8321SBarry Smith PetscErrorCode ierr; 36483c7409f5SSatish Balay 36493a40ed3dSBarry Smith PetscFunctionBegin; 36500700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3651639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 36521cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 365394b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 36543a40ed3dSBarry Smith PetscFunctionReturn(0); 36553c7409f5SSatish Balay } 36563c7409f5SSatish Balay 36574a2ae208SSatish Balay #undef __FUNCT__ 36584a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 36599ab63eb5SSatish Balay /*@C 36603c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 36613c7409f5SSatish Balay SNES options in the database. 36623c7409f5SSatish Balay 3663c7afd0dbSLois Curfman McInnes Not Collective 3664c7afd0dbSLois Curfman McInnes 36653c7409f5SSatish Balay Input Parameter: 36663c7409f5SSatish Balay . snes - the SNES context 36673c7409f5SSatish Balay 36683c7409f5SSatish Balay Output Parameter: 36693c7409f5SSatish Balay . prefix - pointer to the prefix string used 36703c7409f5SSatish Balay 36714ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 36729ab63eb5SSatish Balay sufficient length to hold the prefix. 36739ab63eb5SSatish Balay 367436851e7fSLois Curfman McInnes Level: advanced 367536851e7fSLois Curfman McInnes 36763c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 3677a86d99e1SLois Curfman McInnes 3678a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 36793c7409f5SSatish Balay @*/ 36807087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 36813c7409f5SSatish Balay { 3682dfbe8321SBarry Smith PetscErrorCode ierr; 36833c7409f5SSatish Balay 36843a40ed3dSBarry Smith PetscFunctionBegin; 36850700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3686639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 36873a40ed3dSBarry Smith PetscFunctionReturn(0); 36883c7409f5SSatish Balay } 36893c7409f5SSatish Balay 3690b2002411SLois Curfman McInnes 36914a2ae208SSatish Balay #undef __FUNCT__ 36924a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 36933cea93caSBarry Smith /*@C 36943cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 36953cea93caSBarry Smith 36967f6c08e0SMatthew Knepley Level: advanced 36973cea93caSBarry Smith @*/ 36987087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3699b2002411SLois Curfman McInnes { 3700e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3701dfbe8321SBarry Smith PetscErrorCode ierr; 3702b2002411SLois Curfman McInnes 3703b2002411SLois Curfman McInnes PetscFunctionBegin; 3704b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3705c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3706b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3707b2002411SLois Curfman McInnes } 3708da9b6338SBarry Smith 3709da9b6338SBarry Smith #undef __FUNCT__ 3710da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 37117087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3712da9b6338SBarry Smith { 3713dfbe8321SBarry Smith PetscErrorCode ierr; 371477431f27SBarry Smith PetscInt N,i,j; 3715da9b6338SBarry Smith Vec u,uh,fh; 3716da9b6338SBarry Smith PetscScalar value; 3717da9b6338SBarry Smith PetscReal norm; 3718da9b6338SBarry Smith 3719da9b6338SBarry Smith PetscFunctionBegin; 3720da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3721da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3722da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3723da9b6338SBarry Smith 3724da9b6338SBarry Smith /* currently only works for sequential */ 3725da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3726da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3727da9b6338SBarry Smith for (i=0; i<N; i++) { 3728da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 372977431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3730da9b6338SBarry Smith for (j=-10; j<11; j++) { 3731ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3732da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 37333ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3734da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 373577431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3736da9b6338SBarry Smith value = -value; 3737da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3738da9b6338SBarry Smith } 3739da9b6338SBarry Smith } 37406bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 37416bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 3742da9b6338SBarry Smith PetscFunctionReturn(0); 3743da9b6338SBarry Smith } 374471f87433Sdalcinl 374571f87433Sdalcinl #undef __FUNCT__ 3746fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 374771f87433Sdalcinl /*@ 3748fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 374971f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 375071f87433Sdalcinl Newton method. 375171f87433Sdalcinl 37523f9fe445SBarry Smith Logically Collective on SNES 375371f87433Sdalcinl 375471f87433Sdalcinl Input Parameters: 375571f87433Sdalcinl + snes - SNES context 375671f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 375771f87433Sdalcinl 375864ba62caSBarry Smith Options Database: 375964ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 376064ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 376164ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 376264ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 376364ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 376464ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 376564ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 376664ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 376764ba62caSBarry Smith 376871f87433Sdalcinl Notes: 376971f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 377071f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 377171f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 377271f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 377371f87433Sdalcinl solver. 377471f87433Sdalcinl 377571f87433Sdalcinl Level: advanced 377671f87433Sdalcinl 377771f87433Sdalcinl Reference: 377871f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 377971f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 378071f87433Sdalcinl 378171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 378271f87433Sdalcinl 3783fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 378471f87433Sdalcinl @*/ 37857087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 378671f87433Sdalcinl { 378771f87433Sdalcinl PetscFunctionBegin; 37880700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3789acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 379071f87433Sdalcinl snes->ksp_ewconv = flag; 379171f87433Sdalcinl PetscFunctionReturn(0); 379271f87433Sdalcinl } 379371f87433Sdalcinl 379471f87433Sdalcinl #undef __FUNCT__ 3795fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 379671f87433Sdalcinl /*@ 3797fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 379871f87433Sdalcinl for computing relative tolerance for linear solvers within an 379971f87433Sdalcinl inexact Newton method. 380071f87433Sdalcinl 380171f87433Sdalcinl Not Collective 380271f87433Sdalcinl 380371f87433Sdalcinl Input Parameter: 380471f87433Sdalcinl . snes - SNES context 380571f87433Sdalcinl 380671f87433Sdalcinl Output Parameter: 380771f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 380871f87433Sdalcinl 380971f87433Sdalcinl Notes: 381071f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 381171f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 381271f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 381371f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 381471f87433Sdalcinl solver. 381571f87433Sdalcinl 381671f87433Sdalcinl Level: advanced 381771f87433Sdalcinl 381871f87433Sdalcinl Reference: 381971f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 382071f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 382171f87433Sdalcinl 382271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 382371f87433Sdalcinl 3824fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 382571f87433Sdalcinl @*/ 38267087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 382771f87433Sdalcinl { 382871f87433Sdalcinl PetscFunctionBegin; 38290700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 383071f87433Sdalcinl PetscValidPointer(flag,2); 383171f87433Sdalcinl *flag = snes->ksp_ewconv; 383271f87433Sdalcinl PetscFunctionReturn(0); 383371f87433Sdalcinl } 383471f87433Sdalcinl 383571f87433Sdalcinl #undef __FUNCT__ 3836fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 383771f87433Sdalcinl /*@ 3838fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 383971f87433Sdalcinl convergence criteria for the linear solvers within an inexact 384071f87433Sdalcinl Newton method. 384171f87433Sdalcinl 38423f9fe445SBarry Smith Logically Collective on SNES 384371f87433Sdalcinl 384471f87433Sdalcinl Input Parameters: 384571f87433Sdalcinl + snes - SNES context 384671f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 384771f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 384871f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 384971f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 385071f87433Sdalcinl (0 <= gamma2 <= 1) 385171f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 385271f87433Sdalcinl . alpha2 - power for safeguard 385371f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 385471f87433Sdalcinl 385571f87433Sdalcinl Note: 385671f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 385771f87433Sdalcinl 385871f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 385971f87433Sdalcinl 386071f87433Sdalcinl Level: advanced 386171f87433Sdalcinl 386271f87433Sdalcinl Reference: 386371f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 386471f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 386571f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 386671f87433Sdalcinl 386771f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 386871f87433Sdalcinl 3869fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 387071f87433Sdalcinl @*/ 38717087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 387271f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 387371f87433Sdalcinl { 3874fa9f3622SBarry Smith SNESKSPEW *kctx; 387571f87433Sdalcinl PetscFunctionBegin; 38760700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3877fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3878e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 3879c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 3880c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 3881c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 3882c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 3883c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 3884c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 3885c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 388671f87433Sdalcinl 388771f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 388871f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 388971f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 389071f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 389171f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 389271f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 389371f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 389471f87433Sdalcinl 389571f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 3896e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 389771f87433Sdalcinl } 389871f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 3899e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 390071f87433Sdalcinl } 390171f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 3902e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 390371f87433Sdalcinl } 390471f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 3905e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 390671f87433Sdalcinl } 390771f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 3908e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 390971f87433Sdalcinl } 391071f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 3911e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 391271f87433Sdalcinl } 391371f87433Sdalcinl PetscFunctionReturn(0); 391471f87433Sdalcinl } 391571f87433Sdalcinl 391671f87433Sdalcinl #undef __FUNCT__ 3917fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 391871f87433Sdalcinl /*@ 3919fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 392071f87433Sdalcinl convergence criteria for the linear solvers within an inexact 392171f87433Sdalcinl Newton method. 392271f87433Sdalcinl 392371f87433Sdalcinl Not Collective 392471f87433Sdalcinl 392571f87433Sdalcinl Input Parameters: 392671f87433Sdalcinl snes - SNES context 392771f87433Sdalcinl 392871f87433Sdalcinl Output Parameters: 392971f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 393071f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 393171f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 393271f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 393371f87433Sdalcinl (0 <= gamma2 <= 1) 393471f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 393571f87433Sdalcinl . alpha2 - power for safeguard 393671f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 393771f87433Sdalcinl 393871f87433Sdalcinl Level: advanced 393971f87433Sdalcinl 394071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 394171f87433Sdalcinl 3942fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 394371f87433Sdalcinl @*/ 39447087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 394571f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 394671f87433Sdalcinl { 3947fa9f3622SBarry Smith SNESKSPEW *kctx; 394871f87433Sdalcinl PetscFunctionBegin; 39490700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3950fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3951e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 395271f87433Sdalcinl if(version) *version = kctx->version; 395371f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 395471f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 395571f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 395671f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 395771f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 395871f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 395971f87433Sdalcinl PetscFunctionReturn(0); 396071f87433Sdalcinl } 396171f87433Sdalcinl 396271f87433Sdalcinl #undef __FUNCT__ 3963fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 3964fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 396571f87433Sdalcinl { 396671f87433Sdalcinl PetscErrorCode ierr; 3967fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 396871f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 396971f87433Sdalcinl 397071f87433Sdalcinl PetscFunctionBegin; 3971e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 397271f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 397371f87433Sdalcinl rtol = kctx->rtol_0; 397471f87433Sdalcinl } else { 397571f87433Sdalcinl if (kctx->version == 1) { 397671f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 397771f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 397871f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 397971f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 398071f87433Sdalcinl } else if (kctx->version == 2) { 398171f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 398271f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 398371f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 398471f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 398571f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 398671f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 398771f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 398871f87433Sdalcinl stol = PetscMax(rtol,stol); 398971f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 399071f87433Sdalcinl /* safeguard: avoid oversolving */ 399171f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 399271f87433Sdalcinl stol = PetscMax(rtol,stol); 399371f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 3994e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 399571f87433Sdalcinl } 399671f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 399771f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 399871f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 399971f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 400071f87433Sdalcinl PetscFunctionReturn(0); 400171f87433Sdalcinl } 400271f87433Sdalcinl 400371f87433Sdalcinl #undef __FUNCT__ 4004fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 4005fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 400671f87433Sdalcinl { 400771f87433Sdalcinl PetscErrorCode ierr; 4008fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 400971f87433Sdalcinl PCSide pcside; 401071f87433Sdalcinl Vec lres; 401171f87433Sdalcinl 401271f87433Sdalcinl PetscFunctionBegin; 4013e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 401471f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 401571f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 401671f87433Sdalcinl if (kctx->version == 1) { 4017b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 401871f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 401971f87433Sdalcinl /* KSP residual is true linear residual */ 402071f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 402171f87433Sdalcinl } else { 402271f87433Sdalcinl /* KSP residual is preconditioned residual */ 402371f87433Sdalcinl /* compute true linear residual norm */ 402471f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 402571f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 402671f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 402771f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 40286bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 402971f87433Sdalcinl } 403071f87433Sdalcinl } 403171f87433Sdalcinl PetscFunctionReturn(0); 403271f87433Sdalcinl } 403371f87433Sdalcinl 403471f87433Sdalcinl #undef __FUNCT__ 403571f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 403671f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 403771f87433Sdalcinl { 403871f87433Sdalcinl PetscErrorCode ierr; 403971f87433Sdalcinl 404071f87433Sdalcinl PetscFunctionBegin; 4041fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 404271f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 4043fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 404471f87433Sdalcinl PetscFunctionReturn(0); 404571f87433Sdalcinl } 40466c699258SBarry Smith 40476c699258SBarry Smith #undef __FUNCT__ 40486c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 40496c699258SBarry Smith /*@ 40506c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 40516c699258SBarry Smith 40523f9fe445SBarry Smith Logically Collective on SNES 40536c699258SBarry Smith 40546c699258SBarry Smith Input Parameters: 40556c699258SBarry Smith + snes - the preconditioner context 40566c699258SBarry Smith - dm - the dm 40576c699258SBarry Smith 40586c699258SBarry Smith Level: intermediate 40596c699258SBarry Smith 40606c699258SBarry Smith 40616c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 40626c699258SBarry Smith @*/ 40637087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 40646c699258SBarry Smith { 40656c699258SBarry Smith PetscErrorCode ierr; 4066345fed2cSBarry Smith KSP ksp; 40676cab3a1bSJed Brown SNESDM sdm; 40686c699258SBarry Smith 40696c699258SBarry Smith PetscFunctionBegin; 40700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4071d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 40726cab3a1bSJed Brown if (snes->dm) { /* Move the SNESDM context over to the new DM unless the new DM already has one */ 40736cab3a1bSJed Brown PetscContainer oldcontainer,container; 40746cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 40756cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr); 40766cab3a1bSJed Brown if (oldcontainer && !container) { 40776cab3a1bSJed Brown ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr); 40786cab3a1bSJed Brown ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr); 40796cab3a1bSJed Brown if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */ 40806cab3a1bSJed Brown sdm->originaldm = dm; 40816cab3a1bSJed Brown } 40826cab3a1bSJed Brown } 40836bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 40846cab3a1bSJed Brown } 40856c699258SBarry Smith snes->dm = dm; 4086345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4087345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4088f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 40892c155ee1SBarry Smith if (snes->pc) { 40902c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 40912c155ee1SBarry Smith } 40926c699258SBarry Smith PetscFunctionReturn(0); 40936c699258SBarry Smith } 40946c699258SBarry Smith 40956c699258SBarry Smith #undef __FUNCT__ 40966c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 40976c699258SBarry Smith /*@ 40986c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 40996c699258SBarry Smith 41003f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 41016c699258SBarry Smith 41026c699258SBarry Smith Input Parameter: 41036c699258SBarry Smith . snes - the preconditioner context 41046c699258SBarry Smith 41056c699258SBarry Smith Output Parameter: 41066c699258SBarry Smith . dm - the dm 41076c699258SBarry Smith 41086c699258SBarry Smith Level: intermediate 41096c699258SBarry Smith 41106c699258SBarry Smith 41116c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 41126c699258SBarry Smith @*/ 41137087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 41146c699258SBarry Smith { 41156cab3a1bSJed Brown PetscErrorCode ierr; 41166cab3a1bSJed Brown 41176c699258SBarry Smith PetscFunctionBegin; 41180700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 41196cab3a1bSJed Brown if (!snes->dm) { 41206cab3a1bSJed Brown ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr); 41216cab3a1bSJed Brown } 41226c699258SBarry Smith *dm = snes->dm; 41236c699258SBarry Smith PetscFunctionReturn(0); 41246c699258SBarry Smith } 41250807856dSBarry Smith 412631823bd8SMatthew G Knepley #undef __FUNCT__ 412731823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 412831823bd8SMatthew G Knepley /*@ 4129fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 413031823bd8SMatthew G Knepley 413131823bd8SMatthew G Knepley Collective on SNES 413231823bd8SMatthew G Knepley 413331823bd8SMatthew G Knepley Input Parameters: 413431823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 413531823bd8SMatthew G Knepley - pc - the preconditioner object 413631823bd8SMatthew G Knepley 413731823bd8SMatthew G Knepley Notes: 413831823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 413931823bd8SMatthew G Knepley to configure it using the API). 414031823bd8SMatthew G Knepley 414131823bd8SMatthew G Knepley Level: developer 414231823bd8SMatthew G Knepley 414331823bd8SMatthew G Knepley .keywords: SNES, set, precondition 414431823bd8SMatthew G Knepley .seealso: SNESGetPC() 414531823bd8SMatthew G Knepley @*/ 414631823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 414731823bd8SMatthew G Knepley { 414831823bd8SMatthew G Knepley PetscErrorCode ierr; 414931823bd8SMatthew G Knepley 415031823bd8SMatthew G Knepley PetscFunctionBegin; 415131823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 415231823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 415331823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 415431823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4155bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 415631823bd8SMatthew G Knepley snes->pc = pc; 415731823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 415831823bd8SMatthew G Knepley PetscFunctionReturn(0); 415931823bd8SMatthew G Knepley } 416031823bd8SMatthew G Knepley 416131823bd8SMatthew G Knepley #undef __FUNCT__ 416231823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 416331823bd8SMatthew G Knepley /*@ 4164fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 416531823bd8SMatthew G Knepley 416631823bd8SMatthew G Knepley Not Collective 416731823bd8SMatthew G Knepley 416831823bd8SMatthew G Knepley Input Parameter: 416931823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 417031823bd8SMatthew G Knepley 417131823bd8SMatthew G Knepley Output Parameter: 417231823bd8SMatthew G Knepley . pc - preconditioner context 417331823bd8SMatthew G Knepley 417431823bd8SMatthew G Knepley Level: developer 417531823bd8SMatthew G Knepley 417631823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 417731823bd8SMatthew G Knepley .seealso: SNESSetPC() 417831823bd8SMatthew G Knepley @*/ 417931823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 418031823bd8SMatthew G Knepley { 418131823bd8SMatthew G Knepley PetscErrorCode ierr; 418231823bd8SMatthew G Knepley 418331823bd8SMatthew G Knepley PetscFunctionBegin; 418431823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 418531823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 418631823bd8SMatthew G Knepley if (!snes->pc) { 418731823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr); 41884a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr); 418931823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 419031823bd8SMatthew G Knepley } 419131823bd8SMatthew G Knepley *pc = snes->pc; 419231823bd8SMatthew G Knepley PetscFunctionReturn(0); 419331823bd8SMatthew G Knepley } 419431823bd8SMatthew G Knepley 419569b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4196c6db04a5SJed Brown #include <mex.h> 419769b4f73cSBarry Smith 41988f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 41998f6e6473SBarry Smith 42000807856dSBarry Smith #undef __FUNCT__ 42010807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 42020807856dSBarry Smith /* 42030807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 42040807856dSBarry Smith SNESSetFunctionMatlab(). 42050807856dSBarry Smith 42060807856dSBarry Smith Collective on SNES 42070807856dSBarry Smith 42080807856dSBarry Smith Input Parameters: 42090807856dSBarry Smith + snes - the SNES context 42100807856dSBarry Smith - x - input vector 42110807856dSBarry Smith 42120807856dSBarry Smith Output Parameter: 42130807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 42140807856dSBarry Smith 42150807856dSBarry Smith Notes: 42160807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 42170807856dSBarry Smith implementations, so most users would not generally call this routine 42180807856dSBarry Smith themselves. 42190807856dSBarry Smith 42200807856dSBarry Smith Level: developer 42210807856dSBarry Smith 42220807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 42230807856dSBarry Smith 42240807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 422561b2408cSBarry Smith */ 42267087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 42270807856dSBarry Smith { 4228e650e774SBarry Smith PetscErrorCode ierr; 42298f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 42308f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 42318f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 423291621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 4233e650e774SBarry Smith 42340807856dSBarry Smith PetscFunctionBegin; 42350807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 42360807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 42370807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 42380807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 42390807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 42400807856dSBarry Smith 42410807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 4242e650e774SBarry Smith 424391621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4244e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4245e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 424691621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 424791621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 424891621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 42498f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 42508f6e6473SBarry Smith prhs[4] = sctx->ctx; 4251b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 4252e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4253e650e774SBarry Smith mxDestroyArray(prhs[0]); 4254e650e774SBarry Smith mxDestroyArray(prhs[1]); 4255e650e774SBarry Smith mxDestroyArray(prhs[2]); 42568f6e6473SBarry Smith mxDestroyArray(prhs[3]); 4257e650e774SBarry Smith mxDestroyArray(plhs[0]); 42580807856dSBarry Smith PetscFunctionReturn(0); 42590807856dSBarry Smith } 42600807856dSBarry Smith 42610807856dSBarry Smith 42620807856dSBarry Smith #undef __FUNCT__ 42630807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 426461b2408cSBarry Smith /* 42650807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 42660807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4267e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 42680807856dSBarry Smith 42690807856dSBarry Smith Logically Collective on SNES 42700807856dSBarry Smith 42710807856dSBarry Smith Input Parameters: 42720807856dSBarry Smith + snes - the SNES context 42730807856dSBarry Smith . r - vector to store function value 42740807856dSBarry Smith - func - function evaluation routine 42750807856dSBarry Smith 42760807856dSBarry Smith Calling sequence of func: 427761b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 42780807856dSBarry Smith 42790807856dSBarry Smith 42800807856dSBarry Smith Notes: 42810807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 42820807856dSBarry Smith $ f'(x) x = -f(x), 42830807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 42840807856dSBarry Smith 42850807856dSBarry Smith Level: beginner 42860807856dSBarry Smith 42870807856dSBarry Smith .keywords: SNES, nonlinear, set, function 42880807856dSBarry Smith 42890807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 429061b2408cSBarry Smith */ 42917087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 42920807856dSBarry Smith { 42930807856dSBarry Smith PetscErrorCode ierr; 42948f6e6473SBarry Smith SNESMatlabContext *sctx; 42950807856dSBarry Smith 42960807856dSBarry Smith PetscFunctionBegin; 42978f6e6473SBarry Smith /* currently sctx is memory bleed */ 42988f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 42998f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 43008f6e6473SBarry Smith /* 43018f6e6473SBarry Smith This should work, but it doesn't 43028f6e6473SBarry Smith sctx->ctx = ctx; 43038f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 43048f6e6473SBarry Smith */ 43058f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 43068f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 43070807856dSBarry Smith PetscFunctionReturn(0); 43080807856dSBarry Smith } 430969b4f73cSBarry Smith 431061b2408cSBarry Smith #undef __FUNCT__ 431161b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 431261b2408cSBarry Smith /* 431361b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 431461b2408cSBarry Smith SNESSetJacobianMatlab(). 431561b2408cSBarry Smith 431661b2408cSBarry Smith Collective on SNES 431761b2408cSBarry Smith 431861b2408cSBarry Smith Input Parameters: 431961b2408cSBarry Smith + snes - the SNES context 432061b2408cSBarry Smith . x - input vector 432161b2408cSBarry Smith . A, B - the matrices 432261b2408cSBarry Smith - ctx - user context 432361b2408cSBarry Smith 432461b2408cSBarry Smith Output Parameter: 432561b2408cSBarry Smith . flag - structure of the matrix 432661b2408cSBarry Smith 432761b2408cSBarry Smith Level: developer 432861b2408cSBarry Smith 432961b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 433061b2408cSBarry Smith 433161b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 433261b2408cSBarry Smith @*/ 43337087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 433461b2408cSBarry Smith { 433561b2408cSBarry Smith PetscErrorCode ierr; 433661b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 433761b2408cSBarry Smith int nlhs = 2,nrhs = 6; 433861b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 433961b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 434061b2408cSBarry Smith 434161b2408cSBarry Smith PetscFunctionBegin; 434261b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 434361b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 434461b2408cSBarry Smith 434561b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 434661b2408cSBarry Smith 434761b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 434861b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 434961b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 435061b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 435161b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 435261b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 435361b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 435461b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 435561b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 435661b2408cSBarry Smith prhs[5] = sctx->ctx; 4357b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 435861b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 435961b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 436061b2408cSBarry Smith mxDestroyArray(prhs[0]); 436161b2408cSBarry Smith mxDestroyArray(prhs[1]); 436261b2408cSBarry Smith mxDestroyArray(prhs[2]); 436361b2408cSBarry Smith mxDestroyArray(prhs[3]); 436461b2408cSBarry Smith mxDestroyArray(prhs[4]); 436561b2408cSBarry Smith mxDestroyArray(plhs[0]); 436661b2408cSBarry Smith mxDestroyArray(plhs[1]); 436761b2408cSBarry Smith PetscFunctionReturn(0); 436861b2408cSBarry Smith } 436961b2408cSBarry Smith 437061b2408cSBarry Smith 437161b2408cSBarry Smith #undef __FUNCT__ 437261b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 437361b2408cSBarry Smith /* 437461b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 437561b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4376e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 437761b2408cSBarry Smith 437861b2408cSBarry Smith Logically Collective on SNES 437961b2408cSBarry Smith 438061b2408cSBarry Smith Input Parameters: 438161b2408cSBarry Smith + snes - the SNES context 438261b2408cSBarry Smith . A,B - Jacobian matrices 438361b2408cSBarry Smith . func - function evaluation routine 438461b2408cSBarry Smith - ctx - user context 438561b2408cSBarry Smith 438661b2408cSBarry Smith Calling sequence of func: 438761b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 438861b2408cSBarry Smith 438961b2408cSBarry Smith 439061b2408cSBarry Smith Level: developer 439161b2408cSBarry Smith 439261b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 439361b2408cSBarry Smith 439461b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 439561b2408cSBarry Smith */ 43967087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 439761b2408cSBarry Smith { 439861b2408cSBarry Smith PetscErrorCode ierr; 439961b2408cSBarry Smith SNESMatlabContext *sctx; 440061b2408cSBarry Smith 440161b2408cSBarry Smith PetscFunctionBegin; 440261b2408cSBarry Smith /* currently sctx is memory bleed */ 440361b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 440461b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 440561b2408cSBarry Smith /* 440661b2408cSBarry Smith This should work, but it doesn't 440761b2408cSBarry Smith sctx->ctx = ctx; 440861b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 440961b2408cSBarry Smith */ 441061b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 441161b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 441261b2408cSBarry Smith PetscFunctionReturn(0); 441361b2408cSBarry Smith } 441469b4f73cSBarry Smith 4415f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4416f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4417f9eb7ae2SShri Abhyankar /* 4418f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4419f9eb7ae2SShri Abhyankar 4420f9eb7ae2SShri Abhyankar Collective on SNES 4421f9eb7ae2SShri Abhyankar 4422f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4423f9eb7ae2SShri Abhyankar @*/ 44247087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4425f9eb7ae2SShri Abhyankar { 4426f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 442748f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4428f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4429f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4430f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4431f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4432f9eb7ae2SShri Abhyankar 4433f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4434f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4435f9eb7ae2SShri Abhyankar 4436f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4437f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4438f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4439f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4440f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4441f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4442f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4443f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4444f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4445f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4446f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4447f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4448f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4449f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4450f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4451f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4452f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4453f9eb7ae2SShri Abhyankar } 4454f9eb7ae2SShri Abhyankar 4455f9eb7ae2SShri Abhyankar 4456f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4457f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4458f9eb7ae2SShri Abhyankar /* 4459e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4460f9eb7ae2SShri Abhyankar 4461f9eb7ae2SShri Abhyankar Level: developer 4462f9eb7ae2SShri Abhyankar 4463f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4464f9eb7ae2SShri Abhyankar 4465f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4466f9eb7ae2SShri Abhyankar */ 44677087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4468f9eb7ae2SShri Abhyankar { 4469f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4470f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4471f9eb7ae2SShri Abhyankar 4472f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4473f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4474f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4475f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4476f9eb7ae2SShri Abhyankar /* 4477f9eb7ae2SShri Abhyankar This should work, but it doesn't 4478f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4479f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4480f9eb7ae2SShri Abhyankar */ 4481f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4482f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4483f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4484f9eb7ae2SShri Abhyankar } 4485f9eb7ae2SShri Abhyankar 448669b4f73cSBarry Smith #endif 4487