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: 996a388c36SPeter 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 1156a388c36SPeter Brune 1166a388c36SPeter Brune #undef __FUNCT__ 1176a388c36SPeter Brune #define __FUNCT__ "SNESGetFunctionDomainError" 1186a388c36SPeter Brune /*@ 119c77b2880SPeter Brune SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction; 1206a388c36SPeter Brune 1216a388c36SPeter Brune Logically Collective on SNES 1226a388c36SPeter Brune 1236a388c36SPeter Brune Input Parameters: 1246a388c36SPeter Brune . snes - the SNES context 1256a388c36SPeter Brune 1266a388c36SPeter Brune Output Parameters: 1276a388c36SPeter Brune . domainerror Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise. 1286a388c36SPeter Brune 1296a388c36SPeter Brune Level: advanced 1306a388c36SPeter Brune 1316a388c36SPeter Brune .keywords: SNES, view 1326a388c36SPeter Brune 1336a388c36SPeter Brune .seealso: SNESSetFunctionDomainError, SNESComputeFunction() 1346a388c36SPeter Brune @*/ 1356a388c36SPeter Brune PetscErrorCode SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror) 1366a388c36SPeter Brune { 1376a388c36SPeter Brune PetscFunctionBegin; 1386a388c36SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1396a388c36SPeter Brune PetscValidPointer(domainerror, 2); 1406a388c36SPeter Brune *domainerror = snes->domainerror; 1416a388c36SPeter Brune PetscFunctionReturn(0); 1426a388c36SPeter Brune } 1436a388c36SPeter Brune 1446a388c36SPeter 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 } 13706cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 13716cab3a1bSJed Brown ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr); 13723a40ed3dSBarry Smith PetscFunctionReturn(0); 13739b94acceSBarry Smith } 13749b94acceSBarry Smith 1375646217ecSPeter Brune 1376646217ecSPeter Brune #undef __FUNCT__ 1377646217ecSPeter Brune #define __FUNCT__ "SNESSetGS" 1378c79ef259SPeter Brune /*@C 1379c79ef259SPeter Brune SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for 1380c79ef259SPeter Brune use with composed nonlinear solvers. 1381c79ef259SPeter Brune 1382c79ef259SPeter Brune Input Parameters: 1383c79ef259SPeter Brune + snes - the SNES context 1384c79ef259SPeter Brune . gsfunc - function evaluation routine 1385c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 1386c79ef259SPeter Brune smoother evaluation routine (may be PETSC_NULL) 1387c79ef259SPeter Brune 1388c79ef259SPeter Brune Calling sequence of func: 1389c79ef259SPeter Brune $ func (SNES snes,Vec x,Vec b,void *ctx); 1390c79ef259SPeter Brune 1391c79ef259SPeter Brune + X - solution vector 1392c79ef259SPeter Brune . B - RHS vector 1393d28543b3SPeter Brune - ctx - optional user-defined Gauss-Seidel context 1394c79ef259SPeter Brune 1395c79ef259SPeter Brune Notes: 1396c79ef259SPeter Brune The GS routines are used by the composed nonlinear solver to generate 1397c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1398c79ef259SPeter Brune 1399d28543b3SPeter Brune Level: intermediate 1400c79ef259SPeter Brune 1401d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1402c79ef259SPeter Brune 1403c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS() 1404c79ef259SPeter Brune @*/ 14056cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx) 14066cab3a1bSJed Brown { 14076cab3a1bSJed Brown PetscErrorCode ierr; 14086cab3a1bSJed Brown DM dm; 14096cab3a1bSJed Brown 1410646217ecSPeter Brune PetscFunctionBegin; 14116cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14126cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 14136cab3a1bSJed Brown ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr); 1414646217ecSPeter Brune PetscFunctionReturn(0); 1415646217ecSPeter Brune } 1416646217ecSPeter Brune 1417d25893d9SBarry Smith #undef __FUNCT__ 141889b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps" 141989b92e6fSPeter Brune /*@ 142089b92e6fSPeter Brune SNESSetGSSweeps - Sets the number of sweeps of GS to use. 142189b92e6fSPeter Brune 142289b92e6fSPeter Brune Input Parameters: 142389b92e6fSPeter Brune + snes - the SNES context 142489b92e6fSPeter Brune - sweeps - the number of sweeps of GS to perform. 142589b92e6fSPeter Brune 142689b92e6fSPeter Brune Level: intermediate 142789b92e6fSPeter Brune 142889b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 142989b92e6fSPeter Brune 143089b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps() 143189b92e6fSPeter Brune @*/ 143289b92e6fSPeter Brune 143389b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) { 143489b92e6fSPeter Brune PetscFunctionBegin; 143589b92e6fSPeter Brune snes->gssweeps = sweeps; 143689b92e6fSPeter Brune PetscFunctionReturn(0); 143789b92e6fSPeter Brune } 143889b92e6fSPeter Brune 143989b92e6fSPeter Brune 144089b92e6fSPeter Brune #undef __FUNCT__ 144189b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps" 144289b92e6fSPeter Brune /*@ 144389b92e6fSPeter Brune SNESGetGSSweeps - Gets the number of sweeps GS will use. 144489b92e6fSPeter Brune 144589b92e6fSPeter Brune Input Parameters: 144689b92e6fSPeter Brune . snes - the SNES context 144789b92e6fSPeter Brune 144889b92e6fSPeter Brune Output Parameters: 144989b92e6fSPeter Brune . sweeps - the number of sweeps of GS to perform. 145089b92e6fSPeter Brune 145189b92e6fSPeter Brune Level: intermediate 145289b92e6fSPeter Brune 145389b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 145489b92e6fSPeter Brune 145589b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps() 145689b92e6fSPeter Brune @*/ 145789b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) { 145889b92e6fSPeter Brune PetscFunctionBegin; 145989b92e6fSPeter Brune *sweeps = snes->gssweeps; 146089b92e6fSPeter Brune PetscFunctionReturn(0); 146189b92e6fSPeter Brune } 146289b92e6fSPeter Brune 146389b92e6fSPeter Brune #undef __FUNCT__ 14648b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 14658b0a5094SBarry Smith PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 14668b0a5094SBarry Smith { 14678b0a5094SBarry Smith PetscErrorCode ierr; 14686cab3a1bSJed Brown void *functx,*jacctx; 14696cab3a1bSJed Brown 14708b0a5094SBarry Smith PetscFunctionBegin; 14716cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 14726cab3a1bSJed Brown ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr); 14738b0a5094SBarry Smith /* A(x)*x - b(x) */ 14746cab3a1bSJed Brown ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr); 14756cab3a1bSJed Brown ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr); 14768b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 14778b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 14788b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 14798b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 14808b0a5094SBarry Smith PetscFunctionReturn(0); 14818b0a5094SBarry Smith } 14828b0a5094SBarry Smith 14838b0a5094SBarry Smith #undef __FUNCT__ 14848b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 14858b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 14868b0a5094SBarry Smith { 14878b0a5094SBarry Smith PetscFunctionBegin; 14888b0a5094SBarry Smith *flag = snes->matstruct; 14898b0a5094SBarry Smith PetscFunctionReturn(0); 14908b0a5094SBarry Smith } 14918b0a5094SBarry Smith 14928b0a5094SBarry Smith #undef __FUNCT__ 14938b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 14948b0a5094SBarry Smith /*@C 14950d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 14968b0a5094SBarry Smith 14978b0a5094SBarry Smith Logically Collective on SNES 14988b0a5094SBarry Smith 14998b0a5094SBarry Smith Input Parameters: 15008b0a5094SBarry Smith + snes - the SNES context 15018b0a5094SBarry Smith . r - vector to store function value 15028b0a5094SBarry Smith . func - function evaluation routine 15038b0a5094SBarry 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) 15048b0a5094SBarry Smith . mat - matrix to store A 15058b0a5094SBarry Smith . mfunc - function to compute matrix value 15068b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 15078b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 15088b0a5094SBarry Smith 15098b0a5094SBarry Smith Calling sequence of func: 15108b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 15118b0a5094SBarry Smith 15128b0a5094SBarry Smith + f - function vector 15138b0a5094SBarry Smith - ctx - optional user-defined function context 15148b0a5094SBarry Smith 15158b0a5094SBarry Smith Calling sequence of mfunc: 15168b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 15178b0a5094SBarry Smith 15188b0a5094SBarry Smith + x - input vector 15198b0a5094SBarry 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(), 15208b0a5094SBarry Smith normally just pass mat in this location 15218b0a5094SBarry Smith . mat - form A(x) matrix 15228b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 15238b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 15248b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 15258b0a5094SBarry Smith 15268b0a5094SBarry Smith Notes: 15278b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 15288b0a5094SBarry Smith 15298b0a5094SBarry 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} 15308b0a5094SBarry 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. 15318b0a5094SBarry Smith 15328b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 15338b0a5094SBarry Smith 15340d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 15350d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 15368b0a5094SBarry Smith 15378b0a5094SBarry 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 15388b0a5094SBarry 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 15398b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 15408b0a5094SBarry Smith 15418b0a5094SBarry Smith Level: beginner 15428b0a5094SBarry Smith 15438b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 15448b0a5094SBarry Smith 15450d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard() 15468b0a5094SBarry Smith @*/ 15478b0a5094SBarry 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) 15488b0a5094SBarry Smith { 15498b0a5094SBarry Smith PetscErrorCode ierr; 15508b0a5094SBarry Smith PetscFunctionBegin; 15518b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15528b0a5094SBarry Smith snes->ops->computepfunction = func; 15538b0a5094SBarry Smith snes->ops->computepjacobian = mfunc; 15548b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 15558b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 15568b0a5094SBarry Smith PetscFunctionReturn(0); 15578b0a5094SBarry Smith } 15588b0a5094SBarry Smith 15598b0a5094SBarry Smith #undef __FUNCT__ 1560d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1561d25893d9SBarry Smith /*@C 1562d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1563d25893d9SBarry Smith 1564d25893d9SBarry Smith Logically Collective on SNES 1565d25893d9SBarry Smith 1566d25893d9SBarry Smith Input Parameters: 1567d25893d9SBarry Smith + snes - the SNES context 1568d25893d9SBarry Smith . func - function evaluation routine 1569d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1570d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1571d25893d9SBarry Smith 1572d25893d9SBarry Smith Calling sequence of func: 1573d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1574d25893d9SBarry Smith 1575d25893d9SBarry Smith . f - function vector 1576d25893d9SBarry Smith - ctx - optional user-defined function context 1577d25893d9SBarry Smith 1578d25893d9SBarry Smith Level: intermediate 1579d25893d9SBarry Smith 1580d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1581d25893d9SBarry Smith 1582d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1583d25893d9SBarry Smith @*/ 1584d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1585d25893d9SBarry Smith { 1586d25893d9SBarry Smith PetscFunctionBegin; 1587d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1588d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1589d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1590d25893d9SBarry Smith PetscFunctionReturn(0); 1591d25893d9SBarry Smith } 1592d25893d9SBarry Smith 15933ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 15943ab0aad5SBarry Smith #undef __FUNCT__ 15951096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 15961096aae1SMatthew Knepley /*@C 15971096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 15981096aae1SMatthew Knepley it assumes a zero right hand side. 15991096aae1SMatthew Knepley 16003f9fe445SBarry Smith Logically Collective on SNES 16011096aae1SMatthew Knepley 16021096aae1SMatthew Knepley Input Parameter: 16031096aae1SMatthew Knepley . snes - the SNES context 16041096aae1SMatthew Knepley 16051096aae1SMatthew Knepley Output Parameter: 1606bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 16071096aae1SMatthew Knepley 16081096aae1SMatthew Knepley Level: intermediate 16091096aae1SMatthew Knepley 16101096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 16111096aae1SMatthew Knepley 161285385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 16131096aae1SMatthew Knepley @*/ 16147087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 16151096aae1SMatthew Knepley { 16161096aae1SMatthew Knepley PetscFunctionBegin; 16170700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16181096aae1SMatthew Knepley PetscValidPointer(rhs,2); 161985385478SLisandro Dalcin *rhs = snes->vec_rhs; 16201096aae1SMatthew Knepley PetscFunctionReturn(0); 16211096aae1SMatthew Knepley } 16221096aae1SMatthew Knepley 16231096aae1SMatthew Knepley #undef __FUNCT__ 16244a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 16259b94acceSBarry Smith /*@ 162636851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 16279b94acceSBarry Smith SNESSetFunction(). 16289b94acceSBarry Smith 1629c7afd0dbSLois Curfman McInnes Collective on SNES 1630c7afd0dbSLois Curfman McInnes 16319b94acceSBarry Smith Input Parameters: 1632c7afd0dbSLois Curfman McInnes + snes - the SNES context 1633c7afd0dbSLois Curfman McInnes - x - input vector 16349b94acceSBarry Smith 16359b94acceSBarry Smith Output Parameter: 16363638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 16379b94acceSBarry Smith 16381bffabb2SLois Curfman McInnes Notes: 163936851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 164036851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 164136851e7fSLois Curfman McInnes themselves. 164236851e7fSLois Curfman McInnes 164336851e7fSLois Curfman McInnes Level: developer 164436851e7fSLois Curfman McInnes 16459b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 16469b94acceSBarry Smith 1647a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 16489b94acceSBarry Smith @*/ 16497087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 16509b94acceSBarry Smith { 1651dfbe8321SBarry Smith PetscErrorCode ierr; 16526cab3a1bSJed Brown DM dm; 16536cab3a1bSJed Brown SNESDM sdm; 16549b94acceSBarry Smith 16553a40ed3dSBarry Smith PetscFunctionBegin; 16560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16570700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 16580700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1659c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1660c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 16614ec14c9cSBarry Smith VecValidValues(x,2,PETSC_TRUE); 1662184914b5SBarry Smith 16636cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 16646cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 1665d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 16666cab3a1bSJed Brown if (sdm->computefunction) { 1667d64ed03dSBarry Smith PetscStackPush("SNES user function"); 16686cab3a1bSJed Brown ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 1669d64ed03dSBarry Smith PetscStackPop; 167073250ac0SBarry Smith } else if (snes->dm) { 1671644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1672c90fad12SPeter Brune } else if (snes->vec_rhs) { 1673c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1674644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 167585385478SLisandro Dalcin if (snes->vec_rhs) { 167685385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 16773ab0aad5SBarry Smith } 1678ae3c334cSLois Curfman McInnes snes->nfuncs++; 1679d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 16804ec14c9cSBarry Smith VecValidValues(y,3,PETSC_FALSE); 16813a40ed3dSBarry Smith PetscFunctionReturn(0); 16829b94acceSBarry Smith } 16839b94acceSBarry Smith 16844a2ae208SSatish Balay #undef __FUNCT__ 1685646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1686c79ef259SPeter Brune /*@ 1687c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1688c79ef259SPeter Brune SNESSetGS(). 1689c79ef259SPeter Brune 1690c79ef259SPeter Brune Collective on SNES 1691c79ef259SPeter Brune 1692c79ef259SPeter Brune Input Parameters: 1693c79ef259SPeter Brune + snes - the SNES context 1694c79ef259SPeter Brune . x - input vector 1695c79ef259SPeter Brune - b - rhs vector 1696c79ef259SPeter Brune 1697c79ef259SPeter Brune Output Parameter: 1698c79ef259SPeter Brune . x - new solution vector 1699c79ef259SPeter Brune 1700c79ef259SPeter Brune Notes: 1701c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1702c79ef259SPeter Brune implementations, so most users would not generally call this routine 1703c79ef259SPeter Brune themselves. 1704c79ef259SPeter Brune 1705c79ef259SPeter Brune Level: developer 1706c79ef259SPeter Brune 1707c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1708c79ef259SPeter Brune 1709c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1710c79ef259SPeter Brune @*/ 1711646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1712646217ecSPeter Brune { 1713646217ecSPeter Brune PetscErrorCode ierr; 171489b92e6fSPeter Brune PetscInt i; 17156cab3a1bSJed Brown DM dm; 17166cab3a1bSJed Brown SNESDM sdm; 1717646217ecSPeter Brune 1718646217ecSPeter Brune PetscFunctionBegin; 1719646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1720646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1721646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1722646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 1723646217ecSPeter Brune if(b) PetscCheckSameComm(snes,1,b,3); 17244ec14c9cSBarry Smith if (b) VecValidValues(b,2,PETSC_TRUE); 1725701cf23dSPeter Brune ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 17266cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 17276cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 17286cab3a1bSJed Brown if (sdm->computegs) { 172989b92e6fSPeter Brune for (i = 0; i < snes->gssweeps; i++) { 1730646217ecSPeter Brune PetscStackPush("SNES user GS"); 17316cab3a1bSJed Brown ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 1732646217ecSPeter Brune PetscStackPop; 173389b92e6fSPeter Brune } 1734646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 1735701cf23dSPeter Brune ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 17364ec14c9cSBarry Smith VecValidValues(x,3,PETSC_FALSE); 1737646217ecSPeter Brune PetscFunctionReturn(0); 1738646217ecSPeter Brune } 1739646217ecSPeter Brune 1740646217ecSPeter Brune 1741646217ecSPeter Brune #undef __FUNCT__ 17424a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 174362fef451SLois Curfman McInnes /*@ 174462fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 174562fef451SLois Curfman McInnes set with SNESSetJacobian(). 174662fef451SLois Curfman McInnes 1747c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1748c7afd0dbSLois Curfman McInnes 174962fef451SLois Curfman McInnes Input Parameters: 1750c7afd0dbSLois Curfman McInnes + snes - the SNES context 1751c7afd0dbSLois Curfman McInnes - x - input vector 175262fef451SLois Curfman McInnes 175362fef451SLois Curfman McInnes Output Parameters: 1754c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 175562fef451SLois Curfman McInnes . B - optional preconditioning matrix 17562b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1757fee21e36SBarry Smith 1758e35cf81dSBarry Smith Options Database Keys: 1759e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1760693365a8SJed Brown . -snes_lag_jacobian <lag> 1761693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1762693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1763693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 17644c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1765c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 1766c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 1767c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 1768c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 1769c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 17704c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 1771c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 1772c01495d3SJed Brown 1773e35cf81dSBarry Smith 177462fef451SLois Curfman McInnes Notes: 177562fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 177662fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 177762fef451SLois Curfman McInnes 177894b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1779dc5a77f8SLois Curfman McInnes flag parameter. 178062fef451SLois Curfman McInnes 178136851e7fSLois Curfman McInnes Level: developer 178236851e7fSLois Curfman McInnes 178362fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 178462fef451SLois Curfman McInnes 1785e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 178662fef451SLois Curfman McInnes @*/ 17877087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 17889b94acceSBarry Smith { 1789dfbe8321SBarry Smith PetscErrorCode ierr; 1790ace3abfcSBarry Smith PetscBool flag; 17916cab3a1bSJed Brown DM dm; 17926cab3a1bSJed Brown SNESDM sdm; 17933a40ed3dSBarry Smith 17943a40ed3dSBarry Smith PetscFunctionBegin; 17950700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 17960700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 17974482741eSBarry Smith PetscValidPointer(flg,5); 1798c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 17994ec14c9cSBarry Smith VecValidValues(X,2,PETSC_TRUE); 18006cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18016cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 18026cab3a1bSJed Brown if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 1803ebd3b9afSBarry Smith 1804ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1805ebd3b9afSBarry Smith 1806fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 1807fe3ffe1eSBarry Smith snes->lagjacobian = -1; 1808fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1809fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 1810e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1811e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1812ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1813ebd3b9afSBarry Smith if (flag) { 1814ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1815ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1816ebd3b9afSBarry Smith } 1817e35cf81dSBarry Smith PetscFunctionReturn(0); 1818e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1819e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1820e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1821ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1822ebd3b9afSBarry Smith if (flag) { 1823ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1824ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1825ebd3b9afSBarry Smith } 1826e35cf81dSBarry Smith PetscFunctionReturn(0); 1827e35cf81dSBarry Smith } 1828e35cf81dSBarry Smith 1829c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 1830e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1831d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 18326cab3a1bSJed Brown ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr); 1833d64ed03dSBarry Smith PetscStackPop; 1834d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1835a8054027SBarry Smith 18363b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 18373b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 18383b4f5425SBarry Smith snes->lagpreconditioner = -1; 18393b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 1840a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1841a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 1842a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 1843a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1844a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 1845a8054027SBarry Smith } 1846a8054027SBarry Smith 18476d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 18480700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 18490700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 1850693365a8SJed Brown { 1851693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 1852693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 1853693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 1854693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 1855693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 1856693365a8SJed Brown if (flag || flag_draw || flag_contour) { 1857693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 1858693365a8SJed Brown MatStructure mstruct; 1859693365a8SJed Brown PetscViewer vdraw,vstdout; 18606b3a5b13SJed Brown PetscBool flg; 1861693365a8SJed Brown if (flag_operator) { 1862693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 1863693365a8SJed Brown Bexp = Bexp_mine; 1864693365a8SJed Brown } else { 1865693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 1866693365a8SJed Brown ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 1867693365a8SJed Brown if (flg) Bexp = *B; 1868693365a8SJed Brown else { 1869693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 1870693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 1871693365a8SJed Brown Bexp = Bexp_mine; 1872693365a8SJed Brown } 1873693365a8SJed Brown } 1874693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 1875693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 1876693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 1877693365a8SJed Brown if (flag_draw || flag_contour) { 1878693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 1879693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 1880693365a8SJed Brown } else vdraw = PETSC_NULL; 1881693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 1882693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 1883693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 1884693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 1885693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1886693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 1887693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1888693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 1889693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1890693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 1891693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 1892693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 1893693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 1894693365a8SJed Brown } 1895693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 1896693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 1897693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 1898693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 1899693365a8SJed Brown } 1900693365a8SJed Brown } 19014c30e9fbSJed Brown { 19026719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 19036719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 19044c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 19056719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 19064c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 19074c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 19086719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 19096719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 19106719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 19116719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 19124c30e9fbSJed Brown Mat Bfd; 19134c30e9fbSJed Brown MatStructure mstruct; 19144c30e9fbSJed Brown PetscViewer vdraw,vstdout; 19154c30e9fbSJed Brown ISColoring iscoloring; 19164c30e9fbSJed Brown MatFDColoring matfdcoloring; 19174c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 19184c30e9fbSJed Brown void *funcctx; 19196719d8e4SJed Brown PetscReal norm1,norm2,normmax; 19204c30e9fbSJed Brown 19214c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 19224c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 19234c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 19244c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 19254c30e9fbSJed Brown 19264c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 19274c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 19284c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 19294c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 19304c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 19314c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 19324c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 19334c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 19344c30e9fbSJed Brown 19354c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 19364c30e9fbSJed Brown if (flag_draw || flag_contour) { 19374c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 19384c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 19394c30e9fbSJed Brown } else vdraw = PETSC_NULL; 19404c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 19416719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 19424c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 19434c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 19446719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 19454c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 19464c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 19474c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 19486719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 19494c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 19506719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 19516719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 19524c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 19534c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 19544c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 19554c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 19564c30e9fbSJed Brown } 19574c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 19586719d8e4SJed Brown 19596719d8e4SJed Brown if (flag_threshold) { 19606719d8e4SJed Brown PetscInt bs,rstart,rend,i; 19616719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 19626719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 19636719d8e4SJed Brown for (i=rstart; i<rend; i++) { 19646719d8e4SJed Brown const PetscScalar *ba,*ca; 19656719d8e4SJed Brown const PetscInt *bj,*cj; 19666719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 19676719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 19686719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 19696719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 19706719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 19716719d8e4SJed Brown for (j=0; j<bn; j++) { 19726719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 19736719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 19746719d8e4SJed Brown maxentrycol = bj[j]; 19756719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 19766719d8e4SJed Brown } 19776719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 19786719d8e4SJed Brown maxdiffcol = bj[j]; 19796719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 19806719d8e4SJed Brown } 19816719d8e4SJed Brown if (rdiff > maxrdiff) { 19826719d8e4SJed Brown maxrdiffcol = bj[j]; 19836719d8e4SJed Brown maxrdiff = rdiff; 19846719d8e4SJed Brown } 19856719d8e4SJed Brown } 19866719d8e4SJed Brown if (maxrdiff > 1) { 19876719d8e4SJed 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); 19886719d8e4SJed Brown for (j=0; j<bn; j++) { 19896719d8e4SJed Brown PetscReal rdiff; 19906719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 19916719d8e4SJed Brown if (rdiff > 1) { 19926719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 19936719d8e4SJed Brown } 19946719d8e4SJed Brown } 19956719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 19966719d8e4SJed Brown } 19976719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 19986719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 19996719d8e4SJed Brown } 20006719d8e4SJed Brown } 20014c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 20024c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 20034c30e9fbSJed Brown } 20044c30e9fbSJed Brown } 20053a40ed3dSBarry Smith PetscFunctionReturn(0); 20069b94acceSBarry Smith } 20079b94acceSBarry Smith 20084a2ae208SSatish Balay #undef __FUNCT__ 20094a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 20109b94acceSBarry Smith /*@C 20119b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2012044dda88SLois Curfman McInnes location to store the matrix. 20139b94acceSBarry Smith 20143f9fe445SBarry Smith Logically Collective on SNES and Mat 2015c7afd0dbSLois Curfman McInnes 20169b94acceSBarry Smith Input Parameters: 2017c7afd0dbSLois Curfman McInnes + snes - the SNES context 20189b94acceSBarry Smith . A - Jacobian matrix 20199b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 2020efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 2021c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 2022efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 20239b94acceSBarry Smith 20249b94acceSBarry Smith Calling sequence of func: 20258d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 20269b94acceSBarry Smith 2027c7afd0dbSLois Curfman McInnes + x - input vector 20289b94acceSBarry Smith . A - Jacobian matrix 20299b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 2030ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 20312b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 2032c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 20339b94acceSBarry Smith 20349b94acceSBarry Smith Notes: 203594b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 20362cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 2037ac21db08SLois Curfman McInnes 2038ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 20399b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 20409b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 20419b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 20429b94acceSBarry Smith throughout the global iterations. 20439b94acceSBarry Smith 204416913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 204516913363SBarry Smith each matrix. 204616913363SBarry Smith 2047a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 2048a8a26c1eSJed Brown must be a MatFDColoring. 2049a8a26c1eSJed Brown 2050c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2051c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2052c3cc8fd1SJed Brown 205336851e7fSLois Curfman McInnes Level: beginner 205436851e7fSLois Curfman McInnes 20559b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 20569b94acceSBarry Smith 20573ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 20589b94acceSBarry Smith @*/ 20597087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 20609b94acceSBarry Smith { 2061dfbe8321SBarry Smith PetscErrorCode ierr; 20626cab3a1bSJed Brown DM dm; 20633a7fca6bSBarry Smith 20643a40ed3dSBarry Smith PetscFunctionBegin; 20650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 20660700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 20670700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 2068c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 206906975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 20706cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 20716cab3a1bSJed Brown ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr); 20723a7fca6bSBarry Smith if (A) { 20737dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 20746bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 20759b94acceSBarry Smith snes->jacobian = A; 20763a7fca6bSBarry Smith } 20773a7fca6bSBarry Smith if (B) { 20787dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 20796bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 20809b94acceSBarry Smith snes->jacobian_pre = B; 20813a7fca6bSBarry Smith } 20823a40ed3dSBarry Smith PetscFunctionReturn(0); 20839b94acceSBarry Smith } 208462fef451SLois Curfman McInnes 20854a2ae208SSatish Balay #undef __FUNCT__ 20864a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 2087c2aafc4cSSatish Balay /*@C 2088b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2089b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2090b4fd4287SBarry Smith 2091c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2092c7afd0dbSLois Curfman McInnes 2093b4fd4287SBarry Smith Input Parameter: 2094b4fd4287SBarry Smith . snes - the nonlinear solver context 2095b4fd4287SBarry Smith 2096b4fd4287SBarry Smith Output Parameters: 2097c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 2098b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 209970e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 210070e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 2101fee21e36SBarry Smith 210236851e7fSLois Curfman McInnes Level: advanced 210336851e7fSLois Curfman McInnes 2104b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 2105b4fd4287SBarry Smith @*/ 21067087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 2107b4fd4287SBarry Smith { 21086cab3a1bSJed Brown PetscErrorCode ierr; 21096cab3a1bSJed Brown DM dm; 21106cab3a1bSJed Brown SNESDM sdm; 21116cab3a1bSJed Brown 21123a40ed3dSBarry Smith PetscFunctionBegin; 21130700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2114b4fd4287SBarry Smith if (A) *A = snes->jacobian; 2115b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 21166cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 21176cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 21186cab3a1bSJed Brown if (func) *func = sdm->computejacobian; 21196cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 21203a40ed3dSBarry Smith PetscFunctionReturn(0); 2121b4fd4287SBarry Smith } 2122b4fd4287SBarry Smith 21239b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 21249b94acceSBarry Smith 21254a2ae208SSatish Balay #undef __FUNCT__ 21264a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 21279b94acceSBarry Smith /*@ 21289b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2129272ac6f2SLois Curfman McInnes of a nonlinear solver. 21309b94acceSBarry Smith 2131fee21e36SBarry Smith Collective on SNES 2132fee21e36SBarry Smith 2133c7afd0dbSLois Curfman McInnes Input Parameters: 213470e92668SMatthew Knepley . snes - the SNES context 2135c7afd0dbSLois Curfman McInnes 2136272ac6f2SLois Curfman McInnes Notes: 2137272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2138272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2139272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2140272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2141272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2142272ac6f2SLois Curfman McInnes 214336851e7fSLois Curfman McInnes Level: advanced 214436851e7fSLois Curfman McInnes 21459b94acceSBarry Smith .keywords: SNES, nonlinear, setup 21469b94acceSBarry Smith 21479b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 21489b94acceSBarry Smith @*/ 21497087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 21509b94acceSBarry Smith { 2151dfbe8321SBarry Smith PetscErrorCode ierr; 21526cab3a1bSJed Brown DM dm; 21536cab3a1bSJed Brown SNESDM sdm; 21543a40ed3dSBarry Smith 21553a40ed3dSBarry Smith PetscFunctionBegin; 21560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 21574dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 21589b94acceSBarry Smith 21597adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 216085385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 216185385478SLisandro Dalcin } 216285385478SLisandro Dalcin 2163a63bb30eSJed Brown ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 216417186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 216558c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 216658c9b817SLisandro Dalcin 216758c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 216858c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 216958c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 217058c9b817SLisandro Dalcin } 217158c9b817SLisandro Dalcin 21726cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 21736cab3a1bSJed Brown ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */ 21746cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 21756cab3a1bSJed Brown if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc"); 21766cab3a1bSJed Brown if (!snes->vec_func) { 21776cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2178214df951SJed Brown } 2179efd51863SBarry Smith 2180b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 2181b710008aSBarry Smith 2182d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 2183d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2184d25893d9SBarry Smith } 2185d25893d9SBarry Smith 2186410397dcSLisandro Dalcin if (snes->ops->setup) { 2187410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2188410397dcSLisandro Dalcin } 218958c9b817SLisandro Dalcin 21907aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 21913a40ed3dSBarry Smith PetscFunctionReturn(0); 21929b94acceSBarry Smith } 21939b94acceSBarry Smith 21944a2ae208SSatish Balay #undef __FUNCT__ 219537596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 219637596af1SLisandro Dalcin /*@ 219737596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 219837596af1SLisandro Dalcin 219937596af1SLisandro Dalcin Collective on SNES 220037596af1SLisandro Dalcin 220137596af1SLisandro Dalcin Input Parameter: 220237596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 220337596af1SLisandro Dalcin 2204d25893d9SBarry Smith Level: intermediate 2205d25893d9SBarry Smith 2206d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 220737596af1SLisandro Dalcin 220837596af1SLisandro Dalcin .keywords: SNES, destroy 220937596af1SLisandro Dalcin 221037596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 221137596af1SLisandro Dalcin @*/ 221237596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 221337596af1SLisandro Dalcin { 221437596af1SLisandro Dalcin PetscErrorCode ierr; 221537596af1SLisandro Dalcin 221637596af1SLisandro Dalcin PetscFunctionBegin; 221737596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2218d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2219d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2220d25893d9SBarry Smith snes->user = PETSC_NULL; 2221d25893d9SBarry Smith } 22228a23116dSBarry Smith if (snes->pc) { 22238a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 22248a23116dSBarry Smith } 22258a23116dSBarry Smith 222637596af1SLisandro Dalcin if (snes->ops->reset) { 222737596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 222837596af1SLisandro Dalcin } 222937596af1SLisandro Dalcin if (snes->ksp) {ierr = KSPReset(snes->ksp);CHKERRQ(ierr);} 22306bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 22316bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 22326bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 22336bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 22346bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 22356bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2236c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2237c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 223837596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 223937596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 224037596af1SLisandro Dalcin PetscFunctionReturn(0); 224137596af1SLisandro Dalcin } 224237596af1SLisandro Dalcin 224337596af1SLisandro Dalcin #undef __FUNCT__ 22444a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 224552baeb72SSatish Balay /*@ 22469b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 22479b94acceSBarry Smith with SNESCreate(). 22489b94acceSBarry Smith 2249c7afd0dbSLois Curfman McInnes Collective on SNES 2250c7afd0dbSLois Curfman McInnes 22519b94acceSBarry Smith Input Parameter: 22529b94acceSBarry Smith . snes - the SNES context 22539b94acceSBarry Smith 225436851e7fSLois Curfman McInnes Level: beginner 225536851e7fSLois Curfman McInnes 22569b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 22579b94acceSBarry Smith 225863a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 22599b94acceSBarry Smith @*/ 22606bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 22619b94acceSBarry Smith { 22626849ba73SBarry Smith PetscErrorCode ierr; 22633a40ed3dSBarry Smith 22643a40ed3dSBarry Smith PetscFunctionBegin; 22656bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 22666bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 22676bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2268d4bb536fSBarry Smith 22696bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 22708a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 22716b8b9a38SLisandro Dalcin 2272be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 22736bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 22746bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 22756d4c513bSLisandro Dalcin 22766bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 22776bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 22786b8b9a38SLisandro Dalcin 22796bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 22806bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 22816bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 22826b8b9a38SLisandro Dalcin } 22836bf464f9SBarry Smith if ((*snes)->conv_malloc) { 22846bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 22856bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 228658c9b817SLisandro Dalcin } 2287ea630c6eSPeter Brune ierr = PetscViewerDestroy(&(*snes)->ls_monitor);CHKERRQ(ierr); 22886bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2289a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 22903a40ed3dSBarry Smith PetscFunctionReturn(0); 22919b94acceSBarry Smith } 22929b94acceSBarry Smith 22939b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 22949b94acceSBarry Smith 22954a2ae208SSatish Balay #undef __FUNCT__ 2296a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2297a8054027SBarry Smith /*@ 2298a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2299a8054027SBarry Smith 23003f9fe445SBarry Smith Logically Collective on SNES 2301a8054027SBarry Smith 2302a8054027SBarry Smith Input Parameters: 2303a8054027SBarry Smith + snes - the SNES context 2304a8054027SBarry 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 23053b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2306a8054027SBarry Smith 2307a8054027SBarry Smith Options Database Keys: 2308a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2309a8054027SBarry Smith 2310a8054027SBarry Smith Notes: 2311a8054027SBarry Smith The default is 1 2312a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2313a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2314a8054027SBarry Smith 2315a8054027SBarry Smith Level: intermediate 2316a8054027SBarry Smith 2317a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2318a8054027SBarry Smith 2319e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2320a8054027SBarry Smith 2321a8054027SBarry Smith @*/ 23227087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2323a8054027SBarry Smith { 2324a8054027SBarry Smith PetscFunctionBegin; 23250700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2326e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2327e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2328c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2329a8054027SBarry Smith snes->lagpreconditioner = lag; 2330a8054027SBarry Smith PetscFunctionReturn(0); 2331a8054027SBarry Smith } 2332a8054027SBarry Smith 2333a8054027SBarry Smith #undef __FUNCT__ 2334efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2335efd51863SBarry Smith /*@ 2336efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2337efd51863SBarry Smith 2338efd51863SBarry Smith Logically Collective on SNES 2339efd51863SBarry Smith 2340efd51863SBarry Smith Input Parameters: 2341efd51863SBarry Smith + snes - the SNES context 2342efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2343efd51863SBarry Smith 2344efd51863SBarry Smith Options Database Keys: 2345efd51863SBarry Smith . -snes_grid_sequence <steps> 2346efd51863SBarry Smith 2347efd51863SBarry Smith Level: intermediate 2348efd51863SBarry Smith 2349c0df2a02SJed Brown Notes: 2350c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2351c0df2a02SJed Brown 2352efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2353efd51863SBarry Smith 2354efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2355efd51863SBarry Smith 2356efd51863SBarry Smith @*/ 2357efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2358efd51863SBarry Smith { 2359efd51863SBarry Smith PetscFunctionBegin; 2360efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2361efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2362efd51863SBarry Smith snes->gridsequence = steps; 2363efd51863SBarry Smith PetscFunctionReturn(0); 2364efd51863SBarry Smith } 2365efd51863SBarry Smith 2366efd51863SBarry Smith #undef __FUNCT__ 2367a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2368a8054027SBarry Smith /*@ 2369a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2370a8054027SBarry Smith 23713f9fe445SBarry Smith Not Collective 2372a8054027SBarry Smith 2373a8054027SBarry Smith Input Parameter: 2374a8054027SBarry Smith . snes - the SNES context 2375a8054027SBarry Smith 2376a8054027SBarry Smith Output Parameter: 2377a8054027SBarry 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 23783b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2379a8054027SBarry Smith 2380a8054027SBarry Smith Options Database Keys: 2381a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2382a8054027SBarry Smith 2383a8054027SBarry Smith Notes: 2384a8054027SBarry Smith The default is 1 2385a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2386a8054027SBarry Smith 2387a8054027SBarry Smith Level: intermediate 2388a8054027SBarry Smith 2389a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2390a8054027SBarry Smith 2391a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2392a8054027SBarry Smith 2393a8054027SBarry Smith @*/ 23947087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2395a8054027SBarry Smith { 2396a8054027SBarry Smith PetscFunctionBegin; 23970700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2398a8054027SBarry Smith *lag = snes->lagpreconditioner; 2399a8054027SBarry Smith PetscFunctionReturn(0); 2400a8054027SBarry Smith } 2401a8054027SBarry Smith 2402a8054027SBarry Smith #undef __FUNCT__ 2403e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2404e35cf81dSBarry Smith /*@ 2405e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2406e35cf81dSBarry Smith often the preconditioner is rebuilt. 2407e35cf81dSBarry Smith 24083f9fe445SBarry Smith Logically Collective on SNES 2409e35cf81dSBarry Smith 2410e35cf81dSBarry Smith Input Parameters: 2411e35cf81dSBarry Smith + snes - the SNES context 2412e35cf81dSBarry 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 2413fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2414e35cf81dSBarry Smith 2415e35cf81dSBarry Smith Options Database Keys: 2416e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2417e35cf81dSBarry Smith 2418e35cf81dSBarry Smith Notes: 2419e35cf81dSBarry Smith The default is 1 2420e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2421fe3ffe1eSBarry 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 2422fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2423e35cf81dSBarry Smith 2424e35cf81dSBarry Smith Level: intermediate 2425e35cf81dSBarry Smith 2426e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2427e35cf81dSBarry Smith 2428e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2429e35cf81dSBarry Smith 2430e35cf81dSBarry Smith @*/ 24317087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2432e35cf81dSBarry Smith { 2433e35cf81dSBarry Smith PetscFunctionBegin; 24340700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2435e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2436e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2437c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2438e35cf81dSBarry Smith snes->lagjacobian = lag; 2439e35cf81dSBarry Smith PetscFunctionReturn(0); 2440e35cf81dSBarry Smith } 2441e35cf81dSBarry Smith 2442e35cf81dSBarry Smith #undef __FUNCT__ 2443e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2444e35cf81dSBarry Smith /*@ 2445e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2446e35cf81dSBarry Smith 24473f9fe445SBarry Smith Not Collective 2448e35cf81dSBarry Smith 2449e35cf81dSBarry Smith Input Parameter: 2450e35cf81dSBarry Smith . snes - the SNES context 2451e35cf81dSBarry Smith 2452e35cf81dSBarry Smith Output Parameter: 2453e35cf81dSBarry 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 2454e35cf81dSBarry Smith the Jacobian is built etc. 2455e35cf81dSBarry Smith 2456e35cf81dSBarry Smith Options Database Keys: 2457e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2458e35cf81dSBarry Smith 2459e35cf81dSBarry Smith Notes: 2460e35cf81dSBarry Smith The default is 1 2461e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2462e35cf81dSBarry Smith 2463e35cf81dSBarry Smith Level: intermediate 2464e35cf81dSBarry Smith 2465e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2466e35cf81dSBarry Smith 2467e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2468e35cf81dSBarry Smith 2469e35cf81dSBarry Smith @*/ 24707087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2471e35cf81dSBarry Smith { 2472e35cf81dSBarry Smith PetscFunctionBegin; 24730700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2474e35cf81dSBarry Smith *lag = snes->lagjacobian; 2475e35cf81dSBarry Smith PetscFunctionReturn(0); 2476e35cf81dSBarry Smith } 2477e35cf81dSBarry Smith 2478e35cf81dSBarry Smith #undef __FUNCT__ 24794a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 24809b94acceSBarry Smith /*@ 2481d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 24829b94acceSBarry Smith 24833f9fe445SBarry Smith Logically Collective on SNES 2484c7afd0dbSLois Curfman McInnes 24859b94acceSBarry Smith Input Parameters: 2486c7afd0dbSLois Curfman McInnes + snes - the SNES context 248770441072SBarry Smith . abstol - absolute convergence tolerance 248833174efeSLois Curfman McInnes . rtol - relative convergence tolerance 248933174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 249033174efeSLois Curfman McInnes of the change in the solution between steps 249133174efeSLois Curfman McInnes . maxit - maximum number of iterations 2492c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2493fee21e36SBarry Smith 249433174efeSLois Curfman McInnes Options Database Keys: 249570441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2496c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2497c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2498c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2499c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 25009b94acceSBarry Smith 2501d7a720efSLois Curfman McInnes Notes: 25029b94acceSBarry Smith The default maximum number of iterations is 50. 25039b94acceSBarry Smith The default maximum number of function evaluations is 1000. 25049b94acceSBarry Smith 250536851e7fSLois Curfman McInnes Level: intermediate 250636851e7fSLois Curfman McInnes 250733174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 25089b94acceSBarry Smith 25092492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 25109b94acceSBarry Smith @*/ 25117087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 25129b94acceSBarry Smith { 25133a40ed3dSBarry Smith PetscFunctionBegin; 25140700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2515c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2516c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2517c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2518c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2519c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2520c5eb9154SBarry Smith 2521ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2522ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2523ab54825eSJed Brown snes->abstol = abstol; 2524ab54825eSJed Brown } 2525ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2526ab54825eSJed 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); 2527ab54825eSJed Brown snes->rtol = rtol; 2528ab54825eSJed Brown } 2529ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2530ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2531ab54825eSJed Brown snes->xtol = stol; 2532ab54825eSJed Brown } 2533ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2534ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2535ab54825eSJed Brown snes->max_its = maxit; 2536ab54825eSJed Brown } 2537ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2538ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2539ab54825eSJed Brown snes->max_funcs = maxf; 2540ab54825eSJed Brown } 25413a40ed3dSBarry Smith PetscFunctionReturn(0); 25429b94acceSBarry Smith } 25439b94acceSBarry Smith 25444a2ae208SSatish Balay #undef __FUNCT__ 25454a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 25469b94acceSBarry Smith /*@ 254733174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 254833174efeSLois Curfman McInnes 2549c7afd0dbSLois Curfman McInnes Not Collective 2550c7afd0dbSLois Curfman McInnes 255133174efeSLois Curfman McInnes Input Parameters: 2552c7afd0dbSLois Curfman McInnes + snes - the SNES context 255385385478SLisandro Dalcin . atol - absolute convergence tolerance 255433174efeSLois Curfman McInnes . rtol - relative convergence tolerance 255533174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 255633174efeSLois Curfman McInnes of the change in the solution between steps 255733174efeSLois Curfman McInnes . maxit - maximum number of iterations 2558c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2559fee21e36SBarry Smith 256033174efeSLois Curfman McInnes Notes: 256133174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 256233174efeSLois Curfman McInnes 256336851e7fSLois Curfman McInnes Level: intermediate 256436851e7fSLois Curfman McInnes 256533174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 256633174efeSLois Curfman McInnes 256733174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 256833174efeSLois Curfman McInnes @*/ 25697087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 257033174efeSLois Curfman McInnes { 25713a40ed3dSBarry Smith PetscFunctionBegin; 25720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 257385385478SLisandro Dalcin if (atol) *atol = snes->abstol; 257433174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 257533174efeSLois Curfman McInnes if (stol) *stol = snes->xtol; 257633174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 257733174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 25783a40ed3dSBarry Smith PetscFunctionReturn(0); 257933174efeSLois Curfman McInnes } 258033174efeSLois Curfman McInnes 25814a2ae208SSatish Balay #undef __FUNCT__ 25824a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 258333174efeSLois Curfman McInnes /*@ 25849b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 25859b94acceSBarry Smith 25863f9fe445SBarry Smith Logically Collective on SNES 2587fee21e36SBarry Smith 2588c7afd0dbSLois Curfman McInnes Input Parameters: 2589c7afd0dbSLois Curfman McInnes + snes - the SNES context 2590c7afd0dbSLois Curfman McInnes - tol - tolerance 2591c7afd0dbSLois Curfman McInnes 25929b94acceSBarry Smith Options Database Key: 2593c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 25949b94acceSBarry Smith 259536851e7fSLois Curfman McInnes Level: intermediate 259636851e7fSLois Curfman McInnes 25979b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 25989b94acceSBarry Smith 25992492ecdbSBarry Smith .seealso: SNESSetTolerances() 26009b94acceSBarry Smith @*/ 26017087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 26029b94acceSBarry Smith { 26033a40ed3dSBarry Smith PetscFunctionBegin; 26040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2605c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 26069b94acceSBarry Smith snes->deltatol = tol; 26073a40ed3dSBarry Smith PetscFunctionReturn(0); 26089b94acceSBarry Smith } 26099b94acceSBarry Smith 2610df9fa365SBarry Smith /* 2611df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2612df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2613df9fa365SBarry Smith macros instead of functions 2614df9fa365SBarry Smith */ 26154a2ae208SSatish Balay #undef __FUNCT__ 2616a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 26177087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2618ce1608b8SBarry Smith { 2619dfbe8321SBarry Smith PetscErrorCode ierr; 2620ce1608b8SBarry Smith 2621ce1608b8SBarry Smith PetscFunctionBegin; 26220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2623a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2624ce1608b8SBarry Smith PetscFunctionReturn(0); 2625ce1608b8SBarry Smith } 2626ce1608b8SBarry Smith 26274a2ae208SSatish Balay #undef __FUNCT__ 2628a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 26297087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2630df9fa365SBarry Smith { 2631dfbe8321SBarry Smith PetscErrorCode ierr; 2632df9fa365SBarry Smith 2633df9fa365SBarry Smith PetscFunctionBegin; 2634a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2635df9fa365SBarry Smith PetscFunctionReturn(0); 2636df9fa365SBarry Smith } 2637df9fa365SBarry Smith 26384a2ae208SSatish Balay #undef __FUNCT__ 2639a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 26406bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2641df9fa365SBarry Smith { 2642dfbe8321SBarry Smith PetscErrorCode ierr; 2643df9fa365SBarry Smith 2644df9fa365SBarry Smith PetscFunctionBegin; 2645a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2646df9fa365SBarry Smith PetscFunctionReturn(0); 2647df9fa365SBarry Smith } 2648df9fa365SBarry Smith 26497087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2650b271bb04SBarry Smith #undef __FUNCT__ 2651b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 26527087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2653b271bb04SBarry Smith { 2654b271bb04SBarry Smith PetscDrawLG lg; 2655b271bb04SBarry Smith PetscErrorCode ierr; 2656b271bb04SBarry Smith PetscReal x,y,per; 2657b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2658b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2659b271bb04SBarry Smith PetscDraw draw; 2660b271bb04SBarry Smith PetscFunctionBegin; 2661b271bb04SBarry Smith if (!monctx) { 2662b271bb04SBarry Smith MPI_Comm comm; 2663b271bb04SBarry Smith 2664b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2665b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2666b271bb04SBarry Smith } 2667b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2668b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2669b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2670b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2671b271bb04SBarry Smith x = (PetscReal) n; 2672b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2673b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2674b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2675b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2676b271bb04SBarry Smith } 2677b271bb04SBarry Smith 2678b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2679b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2680b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2681b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2682b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2683b271bb04SBarry Smith x = (PetscReal) n; 2684b271bb04SBarry Smith y = 100.0*per; 2685b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2686b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2687b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2688b271bb04SBarry Smith } 2689b271bb04SBarry Smith 2690b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2691b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2692b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2693b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2694b271bb04SBarry Smith x = (PetscReal) n; 2695b271bb04SBarry Smith y = (prev - rnorm)/prev; 2696b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2697b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2698b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2699b271bb04SBarry Smith } 2700b271bb04SBarry Smith 2701b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2702b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2703b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2704b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2705b271bb04SBarry Smith x = (PetscReal) n; 2706b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2707b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2708b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2709b271bb04SBarry Smith } 2710b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2711b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2712b271bb04SBarry Smith } 2713b271bb04SBarry Smith prev = rnorm; 2714b271bb04SBarry Smith PetscFunctionReturn(0); 2715b271bb04SBarry Smith } 2716b271bb04SBarry Smith 2717b271bb04SBarry Smith #undef __FUNCT__ 2718b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 27197087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2720b271bb04SBarry Smith { 2721b271bb04SBarry Smith PetscErrorCode ierr; 2722b271bb04SBarry Smith 2723b271bb04SBarry Smith PetscFunctionBegin; 2724b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2725b271bb04SBarry Smith PetscFunctionReturn(0); 2726b271bb04SBarry Smith } 2727b271bb04SBarry Smith 2728b271bb04SBarry Smith #undef __FUNCT__ 2729b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 27306bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2731b271bb04SBarry Smith { 2732b271bb04SBarry Smith PetscErrorCode ierr; 2733b271bb04SBarry Smith 2734b271bb04SBarry Smith PetscFunctionBegin; 2735b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2736b271bb04SBarry Smith PetscFunctionReturn(0); 2737b271bb04SBarry Smith } 2738b271bb04SBarry Smith 27397a03ce2fSLisandro Dalcin #undef __FUNCT__ 27407a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 2741228d79bcSJed Brown /*@ 2742228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 2743228d79bcSJed Brown 2744228d79bcSJed Brown Collective on SNES 2745228d79bcSJed Brown 2746228d79bcSJed Brown Input Parameters: 2747228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 2748228d79bcSJed Brown . iter - iteration number 2749228d79bcSJed Brown - rnorm - relative norm of the residual 2750228d79bcSJed Brown 2751228d79bcSJed Brown Notes: 2752228d79bcSJed Brown This routine is called by the SNES implementations. 2753228d79bcSJed Brown It does not typically need to be called by the user. 2754228d79bcSJed Brown 2755228d79bcSJed Brown Level: developer 2756228d79bcSJed Brown 2757228d79bcSJed Brown .seealso: SNESMonitorSet() 2758228d79bcSJed Brown @*/ 27597a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 27607a03ce2fSLisandro Dalcin { 27617a03ce2fSLisandro Dalcin PetscErrorCode ierr; 27627a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 27637a03ce2fSLisandro Dalcin 27647a03ce2fSLisandro Dalcin PetscFunctionBegin; 27657a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 27667a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 27677a03ce2fSLisandro Dalcin } 27687a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 27697a03ce2fSLisandro Dalcin } 27707a03ce2fSLisandro Dalcin 27719b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 27729b94acceSBarry Smith 27734a2ae208SSatish Balay #undef __FUNCT__ 2774a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 27759b94acceSBarry Smith /*@C 2776a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 27779b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 27789b94acceSBarry Smith progress. 27799b94acceSBarry Smith 27803f9fe445SBarry Smith Logically Collective on SNES 2781fee21e36SBarry Smith 2782c7afd0dbSLois Curfman McInnes Input Parameters: 2783c7afd0dbSLois Curfman McInnes + snes - the SNES context 2784c7afd0dbSLois Curfman McInnes . func - monitoring routine 2785b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 2786e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 2787b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 2788b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 27899b94acceSBarry Smith 2790c7afd0dbSLois Curfman McInnes Calling sequence of func: 2791a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2792c7afd0dbSLois Curfman McInnes 2793c7afd0dbSLois Curfman McInnes + snes - the SNES context 2794c7afd0dbSLois Curfman McInnes . its - iteration number 2795c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 279640a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 27979b94acceSBarry Smith 27989665c990SLois Curfman McInnes Options Database Keys: 2799a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 2800a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 2801a6570f20SBarry Smith uses SNESMonitorLGCreate() 2802cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 2803c7afd0dbSLois Curfman McInnes been hardwired into a code by 2804a6570f20SBarry Smith calls to SNESMonitorSet(), but 2805c7afd0dbSLois Curfman McInnes does not cancel those set via 2806c7afd0dbSLois Curfman McInnes the options database. 28079665c990SLois Curfman McInnes 2808639f9d9dSBarry Smith Notes: 28096bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 2810a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 28116bc08f3fSLois Curfman McInnes order in which they were set. 2812639f9d9dSBarry Smith 2813025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 2814025f1a04SBarry Smith 281536851e7fSLois Curfman McInnes Level: intermediate 281636851e7fSLois Curfman McInnes 28179b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 28189b94acceSBarry Smith 2819a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 28209b94acceSBarry Smith @*/ 2821c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 28229b94acceSBarry Smith { 2823b90d0a6eSBarry Smith PetscInt i; 2824649052a6SBarry Smith PetscErrorCode ierr; 2825b90d0a6eSBarry Smith 28263a40ed3dSBarry Smith PetscFunctionBegin; 28270700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 282817186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2829b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 2830649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 2831649052a6SBarry Smith if (monitordestroy) { 2832c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 2833649052a6SBarry Smith } 2834b90d0a6eSBarry Smith PetscFunctionReturn(0); 2835b90d0a6eSBarry Smith } 2836b90d0a6eSBarry Smith } 2837b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 2838b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 2839639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 28403a40ed3dSBarry Smith PetscFunctionReturn(0); 28419b94acceSBarry Smith } 28429b94acceSBarry Smith 28434a2ae208SSatish Balay #undef __FUNCT__ 2844a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 28455cd90555SBarry Smith /*@C 2846a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 28475cd90555SBarry Smith 28483f9fe445SBarry Smith Logically Collective on SNES 2849c7afd0dbSLois Curfman McInnes 28505cd90555SBarry Smith Input Parameters: 28515cd90555SBarry Smith . snes - the SNES context 28525cd90555SBarry Smith 28531a480d89SAdministrator Options Database Key: 2854a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 2855a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 2856c7afd0dbSLois Curfman McInnes set via the options database 28575cd90555SBarry Smith 28585cd90555SBarry Smith Notes: 28595cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 28605cd90555SBarry Smith 286136851e7fSLois Curfman McInnes Level: intermediate 286236851e7fSLois Curfman McInnes 28635cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 28645cd90555SBarry Smith 2865a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 28665cd90555SBarry Smith @*/ 28677087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 28685cd90555SBarry Smith { 2869d952e501SBarry Smith PetscErrorCode ierr; 2870d952e501SBarry Smith PetscInt i; 2871d952e501SBarry Smith 28725cd90555SBarry Smith PetscFunctionBegin; 28730700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2874d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 2875d952e501SBarry Smith if (snes->monitordestroy[i]) { 28763c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 2877d952e501SBarry Smith } 2878d952e501SBarry Smith } 28795cd90555SBarry Smith snes->numbermonitors = 0; 28805cd90555SBarry Smith PetscFunctionReturn(0); 28815cd90555SBarry Smith } 28825cd90555SBarry Smith 28834a2ae208SSatish Balay #undef __FUNCT__ 28844a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 28859b94acceSBarry Smith /*@C 28869b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 28879b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 28889b94acceSBarry Smith 28893f9fe445SBarry Smith Logically Collective on SNES 2890fee21e36SBarry Smith 2891c7afd0dbSLois Curfman McInnes Input Parameters: 2892c7afd0dbSLois Curfman McInnes + snes - the SNES context 2893c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 28947f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 28957f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 28969b94acceSBarry Smith 2897c7afd0dbSLois Curfman McInnes Calling sequence of func: 289806ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 2899c7afd0dbSLois Curfman McInnes 2900c7afd0dbSLois Curfman McInnes + snes - the SNES context 290106ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 2902c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 2903184914b5SBarry Smith . reason - reason for convergence/divergence 2904c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 29054b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 29064b27c08aSLois Curfman McInnes - f - 2-norm of function 29079b94acceSBarry Smith 290836851e7fSLois Curfman McInnes Level: advanced 290936851e7fSLois Curfman McInnes 29109b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 29119b94acceSBarry Smith 291285385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 29139b94acceSBarry Smith @*/ 29147087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 29159b94acceSBarry Smith { 29167f7931b9SBarry Smith PetscErrorCode ierr; 29177f7931b9SBarry Smith 29183a40ed3dSBarry Smith PetscFunctionBegin; 29190700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 292085385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 29217f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 29227f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 29237f7931b9SBarry Smith } 292485385478SLisandro Dalcin snes->ops->converged = func; 29257f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 292685385478SLisandro Dalcin snes->cnvP = cctx; 29273a40ed3dSBarry Smith PetscFunctionReturn(0); 29289b94acceSBarry Smith } 29299b94acceSBarry Smith 29304a2ae208SSatish Balay #undef __FUNCT__ 29314a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 293252baeb72SSatish Balay /*@ 2933184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 2934184914b5SBarry Smith 2935184914b5SBarry Smith Not Collective 2936184914b5SBarry Smith 2937184914b5SBarry Smith Input Parameter: 2938184914b5SBarry Smith . snes - the SNES context 2939184914b5SBarry Smith 2940184914b5SBarry Smith Output Parameter: 29414d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 2942184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 2943184914b5SBarry Smith 2944184914b5SBarry Smith Level: intermediate 2945184914b5SBarry Smith 2946184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 2947184914b5SBarry Smith 2948184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 2949184914b5SBarry Smith 295085385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 2951184914b5SBarry Smith @*/ 29527087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 2953184914b5SBarry Smith { 2954184914b5SBarry Smith PetscFunctionBegin; 29550700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 29564482741eSBarry Smith PetscValidPointer(reason,2); 2957184914b5SBarry Smith *reason = snes->reason; 2958184914b5SBarry Smith PetscFunctionReturn(0); 2959184914b5SBarry Smith } 2960184914b5SBarry Smith 29614a2ae208SSatish Balay #undef __FUNCT__ 29624a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 2963c9005455SLois Curfman McInnes /*@ 2964c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 2965c9005455SLois Curfman McInnes 29663f9fe445SBarry Smith Logically Collective on SNES 2967fee21e36SBarry Smith 2968c7afd0dbSLois Curfman McInnes Input Parameters: 2969c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 29708c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 2971cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 2972758f92a0SBarry Smith . na - size of a and its 297364731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 2974758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 2975c7afd0dbSLois Curfman McInnes 2976308dcc3eSBarry Smith Notes: 2977308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 2978308dcc3eSBarry Smith default array of length 10000 is allocated. 2979308dcc3eSBarry Smith 2980c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 2981c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 2982c9005455SLois Curfman McInnes during the section of code that is being timed. 2983c9005455SLois Curfman McInnes 298436851e7fSLois Curfman McInnes Level: intermediate 298536851e7fSLois Curfman McInnes 2986c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 2987758f92a0SBarry Smith 298808405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 2989758f92a0SBarry Smith 2990c9005455SLois Curfman McInnes @*/ 29917087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 2992c9005455SLois Curfman McInnes { 2993308dcc3eSBarry Smith PetscErrorCode ierr; 2994308dcc3eSBarry Smith 29953a40ed3dSBarry Smith PetscFunctionBegin; 29960700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 29974482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 2998a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 2999308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 3000308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 3001308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 3002308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 3003308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 3004308dcc3eSBarry Smith } 3005c9005455SLois Curfman McInnes snes->conv_hist = a; 3006758f92a0SBarry Smith snes->conv_hist_its = its; 3007758f92a0SBarry Smith snes->conv_hist_max = na; 3008a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 3009758f92a0SBarry Smith snes->conv_hist_reset = reset; 3010758f92a0SBarry Smith PetscFunctionReturn(0); 3011758f92a0SBarry Smith } 3012758f92a0SBarry Smith 3013308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3014c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 3015c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 3016308dcc3eSBarry Smith EXTERN_C_BEGIN 3017308dcc3eSBarry Smith #undef __FUNCT__ 3018308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 3019308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3020308dcc3eSBarry Smith { 3021308dcc3eSBarry Smith mxArray *mat; 3022308dcc3eSBarry Smith PetscInt i; 3023308dcc3eSBarry Smith PetscReal *ar; 3024308dcc3eSBarry Smith 3025308dcc3eSBarry Smith PetscFunctionBegin; 3026308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3027308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3028308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 3029308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 3030308dcc3eSBarry Smith } 3031308dcc3eSBarry Smith PetscFunctionReturn(mat); 3032308dcc3eSBarry Smith } 3033308dcc3eSBarry Smith EXTERN_C_END 3034308dcc3eSBarry Smith #endif 3035308dcc3eSBarry Smith 3036308dcc3eSBarry Smith 30374a2ae208SSatish Balay #undef __FUNCT__ 30384a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 30390c4c9dddSBarry Smith /*@C 3040758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3041758f92a0SBarry Smith 30423f9fe445SBarry Smith Not Collective 3043758f92a0SBarry Smith 3044758f92a0SBarry Smith Input Parameter: 3045758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3046758f92a0SBarry Smith 3047758f92a0SBarry Smith Output Parameters: 3048758f92a0SBarry Smith . a - array to hold history 3049758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3050758f92a0SBarry Smith negative if not converged) for each solve. 3051758f92a0SBarry Smith - na - size of a and its 3052758f92a0SBarry Smith 3053758f92a0SBarry Smith Notes: 3054758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3055758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3056758f92a0SBarry Smith 3057758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3058758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3059758f92a0SBarry Smith during the section of code that is being timed. 3060758f92a0SBarry Smith 3061758f92a0SBarry Smith Level: intermediate 3062758f92a0SBarry Smith 3063758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3064758f92a0SBarry Smith 3065758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3066758f92a0SBarry Smith 3067758f92a0SBarry Smith @*/ 30687087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3069758f92a0SBarry Smith { 3070758f92a0SBarry Smith PetscFunctionBegin; 30710700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3072758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3073758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3074758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 30753a40ed3dSBarry Smith PetscFunctionReturn(0); 3076c9005455SLois Curfman McInnes } 3077c9005455SLois Curfman McInnes 3078e74ef692SMatthew Knepley #undef __FUNCT__ 3079e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 3080ac226902SBarry Smith /*@C 308176b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3082eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 30837e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 308476b2cf59SMatthew Knepley 30853f9fe445SBarry Smith Logically Collective on SNES 308676b2cf59SMatthew Knepley 308776b2cf59SMatthew Knepley Input Parameters: 308876b2cf59SMatthew Knepley . snes - The nonlinear solver context 308976b2cf59SMatthew Knepley . func - The function 309076b2cf59SMatthew Knepley 309176b2cf59SMatthew Knepley Calling sequence of func: 3092b5d30489SBarry Smith . func (SNES snes, PetscInt step); 309376b2cf59SMatthew Knepley 309476b2cf59SMatthew Knepley . step - The current step of the iteration 309576b2cf59SMatthew Knepley 3096fe97e370SBarry Smith Level: advanced 3097fe97e370SBarry Smith 3098fe97e370SBarry 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() 3099fe97e370SBarry Smith This is not used by most users. 310076b2cf59SMatthew Knepley 310176b2cf59SMatthew Knepley .keywords: SNES, update 3102b5d30489SBarry Smith 310385385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 310476b2cf59SMatthew Knepley @*/ 31057087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 310676b2cf59SMatthew Knepley { 310776b2cf59SMatthew Knepley PetscFunctionBegin; 31080700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3109e7788613SBarry Smith snes->ops->update = func; 311076b2cf59SMatthew Knepley PetscFunctionReturn(0); 311176b2cf59SMatthew Knepley } 311276b2cf59SMatthew Knepley 3113e74ef692SMatthew Knepley #undef __FUNCT__ 3114e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 311576b2cf59SMatthew Knepley /*@ 311676b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 311776b2cf59SMatthew Knepley 311876b2cf59SMatthew Knepley Not collective 311976b2cf59SMatthew Knepley 312076b2cf59SMatthew Knepley Input Parameters: 312176b2cf59SMatthew Knepley . snes - The nonlinear solver context 312276b2cf59SMatthew Knepley . step - The current step of the iteration 312376b2cf59SMatthew Knepley 3124205452f4SMatthew Knepley Level: intermediate 3125205452f4SMatthew Knepley 312676b2cf59SMatthew Knepley .keywords: SNES, update 3127a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 312876b2cf59SMatthew Knepley @*/ 31297087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 313076b2cf59SMatthew Knepley { 313176b2cf59SMatthew Knepley PetscFunctionBegin; 313276b2cf59SMatthew Knepley PetscFunctionReturn(0); 313376b2cf59SMatthew Knepley } 313476b2cf59SMatthew Knepley 31354a2ae208SSatish Balay #undef __FUNCT__ 31364a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 31379b94acceSBarry Smith /* 31389b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 31399b94acceSBarry Smith positive parameter delta. 31409b94acceSBarry Smith 31419b94acceSBarry Smith Input Parameters: 3142c7afd0dbSLois Curfman McInnes + snes - the SNES context 31439b94acceSBarry Smith . y - approximate solution of linear system 31449b94acceSBarry Smith . fnorm - 2-norm of current function 3145c7afd0dbSLois Curfman McInnes - delta - trust region size 31469b94acceSBarry Smith 31479b94acceSBarry Smith Output Parameters: 3148c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 31499b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 31509b94acceSBarry Smith region, and exceeds zero otherwise. 3151c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 31529b94acceSBarry Smith 31539b94acceSBarry Smith Note: 31544b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 31559b94acceSBarry Smith is set to be the maximum allowable step size. 31569b94acceSBarry Smith 31579b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 31589b94acceSBarry Smith */ 3159dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 31609b94acceSBarry Smith { 3161064f8208SBarry Smith PetscReal nrm; 3162ea709b57SSatish Balay PetscScalar cnorm; 3163dfbe8321SBarry Smith PetscErrorCode ierr; 31643a40ed3dSBarry Smith 31653a40ed3dSBarry Smith PetscFunctionBegin; 31660700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31670700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3168c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3169184914b5SBarry Smith 3170064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3171064f8208SBarry Smith if (nrm > *delta) { 3172064f8208SBarry Smith nrm = *delta/nrm; 3173064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3174064f8208SBarry Smith cnorm = nrm; 31752dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 31769b94acceSBarry Smith *ynorm = *delta; 31779b94acceSBarry Smith } else { 31789b94acceSBarry Smith *gpnorm = 0.0; 3179064f8208SBarry Smith *ynorm = nrm; 31809b94acceSBarry Smith } 31813a40ed3dSBarry Smith PetscFunctionReturn(0); 31829b94acceSBarry Smith } 31839b94acceSBarry Smith 31844a2ae208SSatish Balay #undef __FUNCT__ 31854a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 31866ce558aeSBarry Smith /*@C 3187f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3188f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 31899b94acceSBarry Smith 3190c7afd0dbSLois Curfman McInnes Collective on SNES 3191c7afd0dbSLois Curfman McInnes 3192b2002411SLois Curfman McInnes Input Parameters: 3193c7afd0dbSLois Curfman McInnes + snes - the SNES context 31943cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 319585385478SLisandro Dalcin - x - the solution vector. 31969b94acceSBarry Smith 3197b2002411SLois Curfman McInnes Notes: 31988ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 31998ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 32008ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 32018ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 32028ddd3da0SLois Curfman McInnes 320336851e7fSLois Curfman McInnes Level: beginner 320436851e7fSLois Curfman McInnes 32059b94acceSBarry Smith .keywords: SNES, nonlinear, solve 32069b94acceSBarry Smith 3207c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 32089b94acceSBarry Smith @*/ 32097087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 32109b94acceSBarry Smith { 3211dfbe8321SBarry Smith PetscErrorCode ierr; 3212ace3abfcSBarry Smith PetscBool flg; 3213eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 3214eabae89aSBarry Smith PetscViewer viewer; 3215efd51863SBarry Smith PetscInt grid; 3216a69afd8bSBarry Smith Vec xcreated = PETSC_NULL; 3217052efed2SBarry Smith 32183a40ed3dSBarry Smith PetscFunctionBegin; 32190700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3220a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3221a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 32220700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 322385385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 322485385478SLisandro Dalcin 3225a69afd8bSBarry Smith if (!x && snes->dm) { 3226a69afd8bSBarry Smith ierr = DMCreateGlobalVector(snes->dm,&xcreated);CHKERRQ(ierr); 3227a69afd8bSBarry Smith x = xcreated; 3228a69afd8bSBarry Smith } 3229a69afd8bSBarry Smith 3230a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3231efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3232efd51863SBarry Smith 323385385478SLisandro Dalcin /* set solution vector */ 3234efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 32356bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 323685385478SLisandro Dalcin snes->vec_sol = x; 323785385478SLisandro Dalcin /* set afine vector if provided */ 323885385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 32396bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 324085385478SLisandro Dalcin snes->vec_rhs = b; 324185385478SLisandro Dalcin 324270e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 32433f149594SLisandro Dalcin 32447eee914bSBarry Smith if (!grid) { 32457eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3246d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3247dd568438SSatish Balay } else if (snes->dm) { 3248dd568438SSatish Balay PetscBool ig; 3249dd568438SSatish Balay ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr); 3250dd568438SSatish Balay if (ig) { 32517eee914bSBarry Smith ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr); 32527eee914bSBarry Smith } 3253d25893d9SBarry Smith } 3254dd568438SSatish Balay } 3255d25893d9SBarry Smith 3256abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 325750ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3258d5e45103SBarry Smith 32593f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 32604936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 326185385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 32624936397dSBarry Smith if (snes->domainerror){ 32634936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 32644936397dSBarry Smith snes->domainerror = PETSC_FALSE; 32654936397dSBarry Smith } 326617186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 32673f149594SLisandro Dalcin 32687adad957SLisandro Dalcin ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 3269eabae89aSBarry Smith if (flg && !PetscPreLoadingOn) { 32707adad957SLisandro Dalcin ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 3271eabae89aSBarry Smith ierr = SNESView(snes,viewer);CHKERRQ(ierr); 32726bf464f9SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3273eabae89aSBarry Smith } 3274eabae89aSBarry Smith 327590d69ab7SBarry Smith flg = PETSC_FALSE; 3276acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3277da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 32785968eb51SBarry Smith if (snes->printreason) { 3279a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 32805968eb51SBarry Smith if (snes->reason > 0) { 3281*c7e7b494SJed Brown ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 32825968eb51SBarry Smith } else { 3283*c7e7b494SJed Brown ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 32845968eb51SBarry Smith } 3285a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 32865968eb51SBarry Smith } 32875968eb51SBarry Smith 32888501fc72SJed Brown flg = PETSC_FALSE; 32898501fc72SJed Brown ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 32908501fc72SJed Brown if (flg) { 32918501fc72SJed Brown PetscViewer viewer; 32928501fc72SJed Brown ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 32938501fc72SJed Brown ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 32948501fc72SJed Brown ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 32958501fc72SJed Brown ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 32968501fc72SJed Brown ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 32978501fc72SJed Brown } 32988501fc72SJed Brown 3299e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3300efd51863SBarry Smith if (grid < snes->gridsequence) { 3301efd51863SBarry Smith DM fine; 3302efd51863SBarry Smith Vec xnew; 3303efd51863SBarry Smith Mat interp; 3304efd51863SBarry Smith 3305efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3306e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3307efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3308efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3309efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3310efd51863SBarry Smith x = xnew; 3311efd51863SBarry Smith 3312efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3313efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3314efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3315a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3316efd51863SBarry Smith } 3317efd51863SBarry Smith } 3318a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 33193a40ed3dSBarry Smith PetscFunctionReturn(0); 33209b94acceSBarry Smith } 33219b94acceSBarry Smith 33229b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 33239b94acceSBarry Smith 33244a2ae208SSatish Balay #undef __FUNCT__ 33254a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 332682bf6240SBarry Smith /*@C 33274b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 33289b94acceSBarry Smith 3329fee21e36SBarry Smith Collective on SNES 3330fee21e36SBarry Smith 3331c7afd0dbSLois Curfman McInnes Input Parameters: 3332c7afd0dbSLois Curfman McInnes + snes - the SNES context 3333454a90a3SBarry Smith - type - a known method 3334c7afd0dbSLois Curfman McInnes 3335c7afd0dbSLois Curfman McInnes Options Database Key: 3336454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3337c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3338ae12b187SLois Curfman McInnes 33399b94acceSBarry Smith Notes: 3340e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 33414b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3342c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 33434b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3344c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 33459b94acceSBarry Smith 3346ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3347ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3348ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3349ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3350ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3351ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3352ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3353ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3354ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3355b0a32e0cSBarry Smith appropriate method. 335636851e7fSLois Curfman McInnes 335736851e7fSLois Curfman McInnes Level: intermediate 3358a703fe33SLois Curfman McInnes 3359454a90a3SBarry Smith .keywords: SNES, set, type 3360435da068SBarry Smith 3361435da068SBarry Smith .seealso: SNESType, SNESCreate() 3362435da068SBarry Smith 33639b94acceSBarry Smith @*/ 33647087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 33659b94acceSBarry Smith { 3366dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3367ace3abfcSBarry Smith PetscBool match; 33683a40ed3dSBarry Smith 33693a40ed3dSBarry Smith PetscFunctionBegin; 33700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 33714482741eSBarry Smith PetscValidCharPointer(type,2); 337282bf6240SBarry Smith 33736831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 33740f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 337592ff6ae8SBarry Smith 33764b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3377e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 337875396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 3379b5c23020SJed Brown if (snes->ops->destroy) { 3380b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 3381b5c23020SJed Brown snes->ops->destroy = PETSC_NULL; 3382b5c23020SJed Brown } 338375396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 338475396ef9SLisandro Dalcin snes->ops->setup = 0; 338575396ef9SLisandro Dalcin snes->ops->solve = 0; 338675396ef9SLisandro Dalcin snes->ops->view = 0; 338775396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 338875396ef9SLisandro Dalcin snes->ops->destroy = 0; 338975396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 339075396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3391454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 339203bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 33939fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 33949fb22e1aSBarry Smith if (PetscAMSPublishAll) { 33959fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 33969fb22e1aSBarry Smith } 33979fb22e1aSBarry Smith #endif 33983a40ed3dSBarry Smith PetscFunctionReturn(0); 33999b94acceSBarry Smith } 34009b94acceSBarry Smith 3401a847f771SSatish Balay 34029b94acceSBarry Smith /* --------------------------------------------------------------------- */ 34034a2ae208SSatish Balay #undef __FUNCT__ 34044a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 340552baeb72SSatish Balay /*@ 34069b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3407f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 34089b94acceSBarry Smith 3409fee21e36SBarry Smith Not Collective 3410fee21e36SBarry Smith 341136851e7fSLois Curfman McInnes Level: advanced 341236851e7fSLois Curfman McInnes 34139b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 34149b94acceSBarry Smith 34159b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 34169b94acceSBarry Smith @*/ 34177087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 34189b94acceSBarry Smith { 3419dfbe8321SBarry Smith PetscErrorCode ierr; 342082bf6240SBarry Smith 34213a40ed3dSBarry Smith PetscFunctionBegin; 34221441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 34234c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 34243a40ed3dSBarry Smith PetscFunctionReturn(0); 34259b94acceSBarry Smith } 34269b94acceSBarry Smith 34274a2ae208SSatish Balay #undef __FUNCT__ 34284a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 34299b94acceSBarry Smith /*@C 34309a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 34319b94acceSBarry Smith 3432c7afd0dbSLois Curfman McInnes Not Collective 3433c7afd0dbSLois Curfman McInnes 34349b94acceSBarry Smith Input Parameter: 34354b0e389bSBarry Smith . snes - nonlinear solver context 34369b94acceSBarry Smith 34379b94acceSBarry Smith Output Parameter: 34383a7fca6bSBarry Smith . type - SNES method (a character string) 34399b94acceSBarry Smith 344036851e7fSLois Curfman McInnes Level: intermediate 344136851e7fSLois Curfman McInnes 3442454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 34439b94acceSBarry Smith @*/ 34447087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 34459b94acceSBarry Smith { 34463a40ed3dSBarry Smith PetscFunctionBegin; 34470700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34484482741eSBarry Smith PetscValidPointer(type,2); 34497adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 34503a40ed3dSBarry Smith PetscFunctionReturn(0); 34519b94acceSBarry Smith } 34529b94acceSBarry Smith 34534a2ae208SSatish Balay #undef __FUNCT__ 34544a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 345552baeb72SSatish Balay /*@ 34569b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3457c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 34589b94acceSBarry Smith 3459c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3460c7afd0dbSLois Curfman McInnes 34619b94acceSBarry Smith Input Parameter: 34629b94acceSBarry Smith . snes - the SNES context 34639b94acceSBarry Smith 34649b94acceSBarry Smith Output Parameter: 34659b94acceSBarry Smith . x - the solution 34669b94acceSBarry Smith 346770e92668SMatthew Knepley Level: intermediate 346836851e7fSLois Curfman McInnes 34699b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 34709b94acceSBarry Smith 347185385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 34729b94acceSBarry Smith @*/ 34737087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 34749b94acceSBarry Smith { 34753a40ed3dSBarry Smith PetscFunctionBegin; 34760700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34774482741eSBarry Smith PetscValidPointer(x,2); 347885385478SLisandro Dalcin *x = snes->vec_sol; 347970e92668SMatthew Knepley PetscFunctionReturn(0); 348070e92668SMatthew Knepley } 348170e92668SMatthew Knepley 348270e92668SMatthew Knepley #undef __FUNCT__ 34834a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 348452baeb72SSatish Balay /*@ 34859b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 34869b94acceSBarry Smith stored. 34879b94acceSBarry Smith 3488c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3489c7afd0dbSLois Curfman McInnes 34909b94acceSBarry Smith Input Parameter: 34919b94acceSBarry Smith . snes - the SNES context 34929b94acceSBarry Smith 34939b94acceSBarry Smith Output Parameter: 34949b94acceSBarry Smith . x - the solution update 34959b94acceSBarry Smith 349636851e7fSLois Curfman McInnes Level: advanced 349736851e7fSLois Curfman McInnes 34989b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 34999b94acceSBarry Smith 350085385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 35019b94acceSBarry Smith @*/ 35027087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 35039b94acceSBarry Smith { 35043a40ed3dSBarry Smith PetscFunctionBegin; 35050700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35064482741eSBarry Smith PetscValidPointer(x,2); 350785385478SLisandro Dalcin *x = snes->vec_sol_update; 35083a40ed3dSBarry Smith PetscFunctionReturn(0); 35099b94acceSBarry Smith } 35109b94acceSBarry Smith 35114a2ae208SSatish Balay #undef __FUNCT__ 35124a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 35139b94acceSBarry Smith /*@C 35143638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 35159b94acceSBarry Smith 3516a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 3517c7afd0dbSLois Curfman McInnes 35189b94acceSBarry Smith Input Parameter: 35199b94acceSBarry Smith . snes - the SNES context 35209b94acceSBarry Smith 35219b94acceSBarry Smith Output Parameter: 35227bf4e008SBarry Smith + r - the function (or PETSC_NULL) 352370e92668SMatthew Knepley . func - the function (or PETSC_NULL) 352470e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 35259b94acceSBarry Smith 352636851e7fSLois Curfman McInnes Level: advanced 352736851e7fSLois Curfman McInnes 3528a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 35299b94acceSBarry Smith 35304b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 35319b94acceSBarry Smith @*/ 35327087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 35339b94acceSBarry Smith { 3534a63bb30eSJed Brown PetscErrorCode ierr; 35356cab3a1bSJed Brown DM dm; 3536a63bb30eSJed Brown 35373a40ed3dSBarry Smith PetscFunctionBegin; 35380700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3539a63bb30eSJed Brown if (r) { 3540a63bb30eSJed Brown if (!snes->vec_func) { 3541a63bb30eSJed Brown if (snes->vec_rhs) { 3542a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 3543a63bb30eSJed Brown } else if (snes->vec_sol) { 3544a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 3545a63bb30eSJed Brown } else if (snes->dm) { 3546a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 3547a63bb30eSJed Brown } 3548a63bb30eSJed Brown } 3549a63bb30eSJed Brown *r = snes->vec_func; 3550a63bb30eSJed Brown } 35516cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 35526cab3a1bSJed Brown ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr); 35533a40ed3dSBarry Smith PetscFunctionReturn(0); 35549b94acceSBarry Smith } 35559b94acceSBarry Smith 3556c79ef259SPeter Brune /*@C 3557c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3558c79ef259SPeter Brune 3559c79ef259SPeter Brune Input Parameter: 3560c79ef259SPeter Brune . snes - the SNES context 3561c79ef259SPeter Brune 3562c79ef259SPeter Brune Output Parameter: 3563c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3564c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3565c79ef259SPeter Brune 3566c79ef259SPeter Brune Level: advanced 3567c79ef259SPeter Brune 3568c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3569c79ef259SPeter Brune 3570c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3571c79ef259SPeter Brune @*/ 3572c79ef259SPeter Brune 35734a2ae208SSatish Balay #undef __FUNCT__ 3574646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3575646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3576646217ecSPeter Brune { 35776cab3a1bSJed Brown PetscErrorCode ierr; 35786cab3a1bSJed Brown DM dm; 35796cab3a1bSJed Brown 3580646217ecSPeter Brune PetscFunctionBegin; 3581646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35826cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 35836cab3a1bSJed Brown ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr); 3584646217ecSPeter Brune PetscFunctionReturn(0); 3585646217ecSPeter Brune } 3586646217ecSPeter Brune 35874a2ae208SSatish Balay #undef __FUNCT__ 35884a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 35893c7409f5SSatish Balay /*@C 35903c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3591d850072dSLois Curfman McInnes SNES options in the database. 35923c7409f5SSatish Balay 35933f9fe445SBarry Smith Logically Collective on SNES 3594fee21e36SBarry Smith 3595c7afd0dbSLois Curfman McInnes Input Parameter: 3596c7afd0dbSLois Curfman McInnes + snes - the SNES context 3597c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3598c7afd0dbSLois Curfman McInnes 3599d850072dSLois Curfman McInnes Notes: 3600a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3601c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3602d850072dSLois Curfman McInnes 360336851e7fSLois Curfman McInnes Level: advanced 360436851e7fSLois Curfman McInnes 36053c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3606a86d99e1SLois Curfman McInnes 3607a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 36083c7409f5SSatish Balay @*/ 36097087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 36103c7409f5SSatish Balay { 3611dfbe8321SBarry Smith PetscErrorCode ierr; 36123c7409f5SSatish Balay 36133a40ed3dSBarry Smith PetscFunctionBegin; 36140700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3615639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 36161cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 361794b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 36183a40ed3dSBarry Smith PetscFunctionReturn(0); 36193c7409f5SSatish Balay } 36203c7409f5SSatish Balay 36214a2ae208SSatish Balay #undef __FUNCT__ 36224a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 36233c7409f5SSatish Balay /*@C 3624f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3625d850072dSLois Curfman McInnes SNES options in the database. 36263c7409f5SSatish Balay 36273f9fe445SBarry Smith Logically Collective on SNES 3628fee21e36SBarry Smith 3629c7afd0dbSLois Curfman McInnes Input Parameters: 3630c7afd0dbSLois Curfman McInnes + snes - the SNES context 3631c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3632c7afd0dbSLois Curfman McInnes 3633d850072dSLois Curfman McInnes Notes: 3634a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3635c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3636d850072dSLois Curfman McInnes 363736851e7fSLois Curfman McInnes Level: advanced 363836851e7fSLois Curfman McInnes 36393c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3640a86d99e1SLois Curfman McInnes 3641a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 36423c7409f5SSatish Balay @*/ 36437087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 36443c7409f5SSatish Balay { 3645dfbe8321SBarry Smith PetscErrorCode ierr; 36463c7409f5SSatish Balay 36473a40ed3dSBarry Smith PetscFunctionBegin; 36480700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3649639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 36501cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 365194b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 36523a40ed3dSBarry Smith PetscFunctionReturn(0); 36533c7409f5SSatish Balay } 36543c7409f5SSatish Balay 36554a2ae208SSatish Balay #undef __FUNCT__ 36564a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 36579ab63eb5SSatish Balay /*@C 36583c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 36593c7409f5SSatish Balay SNES options in the database. 36603c7409f5SSatish Balay 3661c7afd0dbSLois Curfman McInnes Not Collective 3662c7afd0dbSLois Curfman McInnes 36633c7409f5SSatish Balay Input Parameter: 36643c7409f5SSatish Balay . snes - the SNES context 36653c7409f5SSatish Balay 36663c7409f5SSatish Balay Output Parameter: 36673c7409f5SSatish Balay . prefix - pointer to the prefix string used 36683c7409f5SSatish Balay 36694ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 36709ab63eb5SSatish Balay sufficient length to hold the prefix. 36719ab63eb5SSatish Balay 367236851e7fSLois Curfman McInnes Level: advanced 367336851e7fSLois Curfman McInnes 36743c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 3675a86d99e1SLois Curfman McInnes 3676a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 36773c7409f5SSatish Balay @*/ 36787087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 36793c7409f5SSatish Balay { 3680dfbe8321SBarry Smith PetscErrorCode ierr; 36813c7409f5SSatish Balay 36823a40ed3dSBarry Smith PetscFunctionBegin; 36830700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3684639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 36853a40ed3dSBarry Smith PetscFunctionReturn(0); 36863c7409f5SSatish Balay } 36873c7409f5SSatish Balay 3688b2002411SLois Curfman McInnes 36894a2ae208SSatish Balay #undef __FUNCT__ 36904a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 36913cea93caSBarry Smith /*@C 36923cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 36933cea93caSBarry Smith 36947f6c08e0SMatthew Knepley Level: advanced 36953cea93caSBarry Smith @*/ 36967087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3697b2002411SLois Curfman McInnes { 3698e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3699dfbe8321SBarry Smith PetscErrorCode ierr; 3700b2002411SLois Curfman McInnes 3701b2002411SLois Curfman McInnes PetscFunctionBegin; 3702b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3703c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3704b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3705b2002411SLois Curfman McInnes } 3706da9b6338SBarry Smith 3707da9b6338SBarry Smith #undef __FUNCT__ 3708da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 37097087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3710da9b6338SBarry Smith { 3711dfbe8321SBarry Smith PetscErrorCode ierr; 371277431f27SBarry Smith PetscInt N,i,j; 3713da9b6338SBarry Smith Vec u,uh,fh; 3714da9b6338SBarry Smith PetscScalar value; 3715da9b6338SBarry Smith PetscReal norm; 3716da9b6338SBarry Smith 3717da9b6338SBarry Smith PetscFunctionBegin; 3718da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3719da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3720da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3721da9b6338SBarry Smith 3722da9b6338SBarry Smith /* currently only works for sequential */ 3723da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3724da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3725da9b6338SBarry Smith for (i=0; i<N; i++) { 3726da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 372777431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3728da9b6338SBarry Smith for (j=-10; j<11; j++) { 3729ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3730da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 37313ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3732da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 373377431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3734da9b6338SBarry Smith value = -value; 3735da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3736da9b6338SBarry Smith } 3737da9b6338SBarry Smith } 37386bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 37396bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 3740da9b6338SBarry Smith PetscFunctionReturn(0); 3741da9b6338SBarry Smith } 374271f87433Sdalcinl 374371f87433Sdalcinl #undef __FUNCT__ 3744fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 374571f87433Sdalcinl /*@ 3746fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 374771f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 374871f87433Sdalcinl Newton method. 374971f87433Sdalcinl 37503f9fe445SBarry Smith Logically Collective on SNES 375171f87433Sdalcinl 375271f87433Sdalcinl Input Parameters: 375371f87433Sdalcinl + snes - SNES context 375471f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 375571f87433Sdalcinl 375664ba62caSBarry Smith Options Database: 375764ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 375864ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 375964ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 376064ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 376164ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 376264ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 376364ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 376464ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 376564ba62caSBarry Smith 376671f87433Sdalcinl Notes: 376771f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 376871f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 376971f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 377071f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 377171f87433Sdalcinl solver. 377271f87433Sdalcinl 377371f87433Sdalcinl Level: advanced 377471f87433Sdalcinl 377571f87433Sdalcinl Reference: 377671f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 377771f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 377871f87433Sdalcinl 377971f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 378071f87433Sdalcinl 3781fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 378271f87433Sdalcinl @*/ 37837087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 378471f87433Sdalcinl { 378571f87433Sdalcinl PetscFunctionBegin; 37860700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3787acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 378871f87433Sdalcinl snes->ksp_ewconv = flag; 378971f87433Sdalcinl PetscFunctionReturn(0); 379071f87433Sdalcinl } 379171f87433Sdalcinl 379271f87433Sdalcinl #undef __FUNCT__ 3793fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 379471f87433Sdalcinl /*@ 3795fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 379671f87433Sdalcinl for computing relative tolerance for linear solvers within an 379771f87433Sdalcinl inexact Newton method. 379871f87433Sdalcinl 379971f87433Sdalcinl Not Collective 380071f87433Sdalcinl 380171f87433Sdalcinl Input Parameter: 380271f87433Sdalcinl . snes - SNES context 380371f87433Sdalcinl 380471f87433Sdalcinl Output Parameter: 380571f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 380671f87433Sdalcinl 380771f87433Sdalcinl Notes: 380871f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 380971f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 381071f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 381171f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 381271f87433Sdalcinl solver. 381371f87433Sdalcinl 381471f87433Sdalcinl Level: advanced 381571f87433Sdalcinl 381671f87433Sdalcinl Reference: 381771f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 381871f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 381971f87433Sdalcinl 382071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 382171f87433Sdalcinl 3822fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 382371f87433Sdalcinl @*/ 38247087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 382571f87433Sdalcinl { 382671f87433Sdalcinl PetscFunctionBegin; 38270700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 382871f87433Sdalcinl PetscValidPointer(flag,2); 382971f87433Sdalcinl *flag = snes->ksp_ewconv; 383071f87433Sdalcinl PetscFunctionReturn(0); 383171f87433Sdalcinl } 383271f87433Sdalcinl 383371f87433Sdalcinl #undef __FUNCT__ 3834fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 383571f87433Sdalcinl /*@ 3836fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 383771f87433Sdalcinl convergence criteria for the linear solvers within an inexact 383871f87433Sdalcinl Newton method. 383971f87433Sdalcinl 38403f9fe445SBarry Smith Logically Collective on SNES 384171f87433Sdalcinl 384271f87433Sdalcinl Input Parameters: 384371f87433Sdalcinl + snes - SNES context 384471f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 384571f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 384671f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 384771f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 384871f87433Sdalcinl (0 <= gamma2 <= 1) 384971f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 385071f87433Sdalcinl . alpha2 - power for safeguard 385171f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 385271f87433Sdalcinl 385371f87433Sdalcinl Note: 385471f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 385571f87433Sdalcinl 385671f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 385771f87433Sdalcinl 385871f87433Sdalcinl Level: advanced 385971f87433Sdalcinl 386071f87433Sdalcinl Reference: 386171f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 386271f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 386371f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 386471f87433Sdalcinl 386571f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 386671f87433Sdalcinl 3867fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 386871f87433Sdalcinl @*/ 38697087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 387071f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 387171f87433Sdalcinl { 3872fa9f3622SBarry Smith SNESKSPEW *kctx; 387371f87433Sdalcinl PetscFunctionBegin; 38740700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3875fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3876e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 3877c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 3878c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 3879c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 3880c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 3881c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 3882c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 3883c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 388471f87433Sdalcinl 388571f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 388671f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 388771f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 388871f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 388971f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 389071f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 389171f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 389271f87433Sdalcinl 389371f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 3894e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 389571f87433Sdalcinl } 389671f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 3897e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 389871f87433Sdalcinl } 389971f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 3900e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 390171f87433Sdalcinl } 390271f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 3903e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 390471f87433Sdalcinl } 390571f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 3906e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 390771f87433Sdalcinl } 390871f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 3909e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 391071f87433Sdalcinl } 391171f87433Sdalcinl PetscFunctionReturn(0); 391271f87433Sdalcinl } 391371f87433Sdalcinl 391471f87433Sdalcinl #undef __FUNCT__ 3915fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 391671f87433Sdalcinl /*@ 3917fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 391871f87433Sdalcinl convergence criteria for the linear solvers within an inexact 391971f87433Sdalcinl Newton method. 392071f87433Sdalcinl 392171f87433Sdalcinl Not Collective 392271f87433Sdalcinl 392371f87433Sdalcinl Input Parameters: 392471f87433Sdalcinl snes - SNES context 392571f87433Sdalcinl 392671f87433Sdalcinl Output Parameters: 392771f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 392871f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 392971f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 393071f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 393171f87433Sdalcinl (0 <= gamma2 <= 1) 393271f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 393371f87433Sdalcinl . alpha2 - power for safeguard 393471f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 393571f87433Sdalcinl 393671f87433Sdalcinl Level: advanced 393771f87433Sdalcinl 393871f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 393971f87433Sdalcinl 3940fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 394171f87433Sdalcinl @*/ 39427087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 394371f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 394471f87433Sdalcinl { 3945fa9f3622SBarry Smith SNESKSPEW *kctx; 394671f87433Sdalcinl PetscFunctionBegin; 39470700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3948fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3949e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 395071f87433Sdalcinl if(version) *version = kctx->version; 395171f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 395271f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 395371f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 395471f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 395571f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 395671f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 395771f87433Sdalcinl PetscFunctionReturn(0); 395871f87433Sdalcinl } 395971f87433Sdalcinl 396071f87433Sdalcinl #undef __FUNCT__ 3961fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 3962fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 396371f87433Sdalcinl { 396471f87433Sdalcinl PetscErrorCode ierr; 3965fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 396671f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 396771f87433Sdalcinl 396871f87433Sdalcinl PetscFunctionBegin; 3969e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 397071f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 397171f87433Sdalcinl rtol = kctx->rtol_0; 397271f87433Sdalcinl } else { 397371f87433Sdalcinl if (kctx->version == 1) { 397471f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 397571f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 397671f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 397771f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 397871f87433Sdalcinl } else if (kctx->version == 2) { 397971f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 398071f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 398171f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 398271f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 398371f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 398471f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 398571f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 398671f87433Sdalcinl stol = PetscMax(rtol,stol); 398771f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 398871f87433Sdalcinl /* safeguard: avoid oversolving */ 398971f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 399071f87433Sdalcinl stol = PetscMax(rtol,stol); 399171f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 3992e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 399371f87433Sdalcinl } 399471f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 399571f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 399671f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 399771f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 399871f87433Sdalcinl PetscFunctionReturn(0); 399971f87433Sdalcinl } 400071f87433Sdalcinl 400171f87433Sdalcinl #undef __FUNCT__ 4002fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 4003fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 400471f87433Sdalcinl { 400571f87433Sdalcinl PetscErrorCode ierr; 4006fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 400771f87433Sdalcinl PCSide pcside; 400871f87433Sdalcinl Vec lres; 400971f87433Sdalcinl 401071f87433Sdalcinl PetscFunctionBegin; 4011e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 401271f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 401371f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 401471f87433Sdalcinl if (kctx->version == 1) { 4015b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 401671f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 401771f87433Sdalcinl /* KSP residual is true linear residual */ 401871f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 401971f87433Sdalcinl } else { 402071f87433Sdalcinl /* KSP residual is preconditioned residual */ 402171f87433Sdalcinl /* compute true linear residual norm */ 402271f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 402371f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 402471f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 402571f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 40266bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 402771f87433Sdalcinl } 402871f87433Sdalcinl } 402971f87433Sdalcinl PetscFunctionReturn(0); 403071f87433Sdalcinl } 403171f87433Sdalcinl 403271f87433Sdalcinl #undef __FUNCT__ 403371f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 403471f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 403571f87433Sdalcinl { 403671f87433Sdalcinl PetscErrorCode ierr; 403771f87433Sdalcinl 403871f87433Sdalcinl PetscFunctionBegin; 4039fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 404071f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 4041fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 404271f87433Sdalcinl PetscFunctionReturn(0); 404371f87433Sdalcinl } 40446c699258SBarry Smith 40456c699258SBarry Smith #undef __FUNCT__ 40466c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 40476c699258SBarry Smith /*@ 40486c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 40496c699258SBarry Smith 40503f9fe445SBarry Smith Logically Collective on SNES 40516c699258SBarry Smith 40526c699258SBarry Smith Input Parameters: 40536c699258SBarry Smith + snes - the preconditioner context 40546c699258SBarry Smith - dm - the dm 40556c699258SBarry Smith 40566c699258SBarry Smith Level: intermediate 40576c699258SBarry Smith 40586c699258SBarry Smith 40596c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 40606c699258SBarry Smith @*/ 40617087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 40626c699258SBarry Smith { 40636c699258SBarry Smith PetscErrorCode ierr; 4064345fed2cSBarry Smith KSP ksp; 40656cab3a1bSJed Brown SNESDM sdm; 40666c699258SBarry Smith 40676c699258SBarry Smith PetscFunctionBegin; 40680700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4069d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 40706cab3a1bSJed Brown if (snes->dm) { /* Move the SNESDM context over to the new DM unless the new DM already has one */ 40716cab3a1bSJed Brown PetscContainer oldcontainer,container; 40726cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 40736cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr); 40746cab3a1bSJed Brown if (oldcontainer && !container) { 40756cab3a1bSJed Brown ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr); 40766cab3a1bSJed Brown ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr); 40776cab3a1bSJed Brown if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */ 40786cab3a1bSJed Brown sdm->originaldm = dm; 40796cab3a1bSJed Brown } 40806cab3a1bSJed Brown } 40816bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 40826cab3a1bSJed Brown } 40836c699258SBarry Smith snes->dm = dm; 4084345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4085345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4086f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 40872c155ee1SBarry Smith if (snes->pc) { 40882c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 40892c155ee1SBarry Smith } 40906c699258SBarry Smith PetscFunctionReturn(0); 40916c699258SBarry Smith } 40926c699258SBarry Smith 40936c699258SBarry Smith #undef __FUNCT__ 40946c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 40956c699258SBarry Smith /*@ 40966c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 40976c699258SBarry Smith 40983f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 40996c699258SBarry Smith 41006c699258SBarry Smith Input Parameter: 41016c699258SBarry Smith . snes - the preconditioner context 41026c699258SBarry Smith 41036c699258SBarry Smith Output Parameter: 41046c699258SBarry Smith . dm - the dm 41056c699258SBarry Smith 41066c699258SBarry Smith Level: intermediate 41076c699258SBarry Smith 41086c699258SBarry Smith 41096c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 41106c699258SBarry Smith @*/ 41117087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 41126c699258SBarry Smith { 41136cab3a1bSJed Brown PetscErrorCode ierr; 41146cab3a1bSJed Brown 41156c699258SBarry Smith PetscFunctionBegin; 41160700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 41176cab3a1bSJed Brown if (!snes->dm) { 41186cab3a1bSJed Brown ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr); 41196cab3a1bSJed Brown } 41206c699258SBarry Smith *dm = snes->dm; 41216c699258SBarry Smith PetscFunctionReturn(0); 41226c699258SBarry Smith } 41230807856dSBarry Smith 412431823bd8SMatthew G Knepley #undef __FUNCT__ 412531823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 412631823bd8SMatthew G Knepley /*@ 4127fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 412831823bd8SMatthew G Knepley 412931823bd8SMatthew G Knepley Collective on SNES 413031823bd8SMatthew G Knepley 413131823bd8SMatthew G Knepley Input Parameters: 413231823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 413331823bd8SMatthew G Knepley - pc - the preconditioner object 413431823bd8SMatthew G Knepley 413531823bd8SMatthew G Knepley Notes: 413631823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 413731823bd8SMatthew G Knepley to configure it using the API). 413831823bd8SMatthew G Knepley 413931823bd8SMatthew G Knepley Level: developer 414031823bd8SMatthew G Knepley 414131823bd8SMatthew G Knepley .keywords: SNES, set, precondition 414231823bd8SMatthew G Knepley .seealso: SNESGetPC() 414331823bd8SMatthew G Knepley @*/ 414431823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 414531823bd8SMatthew G Knepley { 414631823bd8SMatthew G Knepley PetscErrorCode ierr; 414731823bd8SMatthew G Knepley 414831823bd8SMatthew G Knepley PetscFunctionBegin; 414931823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 415031823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 415131823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 415231823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4153bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 415431823bd8SMatthew G Knepley snes->pc = pc; 415531823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 415631823bd8SMatthew G Knepley PetscFunctionReturn(0); 415731823bd8SMatthew G Knepley } 415831823bd8SMatthew G Knepley 415931823bd8SMatthew G Knepley #undef __FUNCT__ 416031823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 416131823bd8SMatthew G Knepley /*@ 4162fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 416331823bd8SMatthew G Knepley 416431823bd8SMatthew G Knepley Not Collective 416531823bd8SMatthew G Knepley 416631823bd8SMatthew G Knepley Input Parameter: 416731823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 416831823bd8SMatthew G Knepley 416931823bd8SMatthew G Knepley Output Parameter: 417031823bd8SMatthew G Knepley . pc - preconditioner context 417131823bd8SMatthew G Knepley 417231823bd8SMatthew G Knepley Level: developer 417331823bd8SMatthew G Knepley 417431823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 417531823bd8SMatthew G Knepley .seealso: SNESSetPC() 417631823bd8SMatthew G Knepley @*/ 417731823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 417831823bd8SMatthew G Knepley { 417931823bd8SMatthew G Knepley PetscErrorCode ierr; 418031823bd8SMatthew G Knepley 418131823bd8SMatthew G Knepley PetscFunctionBegin; 418231823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 418331823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 418431823bd8SMatthew G Knepley if (!snes->pc) { 418531823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr); 41864a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr); 418731823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 418831823bd8SMatthew G Knepley } 418931823bd8SMatthew G Knepley *pc = snes->pc; 419031823bd8SMatthew G Knepley PetscFunctionReturn(0); 419131823bd8SMatthew G Knepley } 419231823bd8SMatthew G Knepley 419369b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4194c6db04a5SJed Brown #include <mex.h> 419569b4f73cSBarry Smith 41968f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 41978f6e6473SBarry Smith 41980807856dSBarry Smith #undef __FUNCT__ 41990807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 42000807856dSBarry Smith /* 42010807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 42020807856dSBarry Smith SNESSetFunctionMatlab(). 42030807856dSBarry Smith 42040807856dSBarry Smith Collective on SNES 42050807856dSBarry Smith 42060807856dSBarry Smith Input Parameters: 42070807856dSBarry Smith + snes - the SNES context 42080807856dSBarry Smith - x - input vector 42090807856dSBarry Smith 42100807856dSBarry Smith Output Parameter: 42110807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 42120807856dSBarry Smith 42130807856dSBarry Smith Notes: 42140807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 42150807856dSBarry Smith implementations, so most users would not generally call this routine 42160807856dSBarry Smith themselves. 42170807856dSBarry Smith 42180807856dSBarry Smith Level: developer 42190807856dSBarry Smith 42200807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 42210807856dSBarry Smith 42220807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 422361b2408cSBarry Smith */ 42247087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 42250807856dSBarry Smith { 4226e650e774SBarry Smith PetscErrorCode ierr; 42278f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 42288f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 42298f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 423091621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 4231e650e774SBarry Smith 42320807856dSBarry Smith PetscFunctionBegin; 42330807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 42340807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 42350807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 42360807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 42370807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 42380807856dSBarry Smith 42390807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 4240e650e774SBarry Smith 424191621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4242e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4243e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 424491621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 424591621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 424691621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 42478f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 42488f6e6473SBarry Smith prhs[4] = sctx->ctx; 4249b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 4250e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4251e650e774SBarry Smith mxDestroyArray(prhs[0]); 4252e650e774SBarry Smith mxDestroyArray(prhs[1]); 4253e650e774SBarry Smith mxDestroyArray(prhs[2]); 42548f6e6473SBarry Smith mxDestroyArray(prhs[3]); 4255e650e774SBarry Smith mxDestroyArray(plhs[0]); 42560807856dSBarry Smith PetscFunctionReturn(0); 42570807856dSBarry Smith } 42580807856dSBarry Smith 42590807856dSBarry Smith 42600807856dSBarry Smith #undef __FUNCT__ 42610807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 426261b2408cSBarry Smith /* 42630807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 42640807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4265e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 42660807856dSBarry Smith 42670807856dSBarry Smith Logically Collective on SNES 42680807856dSBarry Smith 42690807856dSBarry Smith Input Parameters: 42700807856dSBarry Smith + snes - the SNES context 42710807856dSBarry Smith . r - vector to store function value 42720807856dSBarry Smith - func - function evaluation routine 42730807856dSBarry Smith 42740807856dSBarry Smith Calling sequence of func: 427561b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 42760807856dSBarry Smith 42770807856dSBarry Smith 42780807856dSBarry Smith Notes: 42790807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 42800807856dSBarry Smith $ f'(x) x = -f(x), 42810807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 42820807856dSBarry Smith 42830807856dSBarry Smith Level: beginner 42840807856dSBarry Smith 42850807856dSBarry Smith .keywords: SNES, nonlinear, set, function 42860807856dSBarry Smith 42870807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 428861b2408cSBarry Smith */ 42897087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 42900807856dSBarry Smith { 42910807856dSBarry Smith PetscErrorCode ierr; 42928f6e6473SBarry Smith SNESMatlabContext *sctx; 42930807856dSBarry Smith 42940807856dSBarry Smith PetscFunctionBegin; 42958f6e6473SBarry Smith /* currently sctx is memory bleed */ 42968f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 42978f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 42988f6e6473SBarry Smith /* 42998f6e6473SBarry Smith This should work, but it doesn't 43008f6e6473SBarry Smith sctx->ctx = ctx; 43018f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 43028f6e6473SBarry Smith */ 43038f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 43048f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 43050807856dSBarry Smith PetscFunctionReturn(0); 43060807856dSBarry Smith } 430769b4f73cSBarry Smith 430861b2408cSBarry Smith #undef __FUNCT__ 430961b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 431061b2408cSBarry Smith /* 431161b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 431261b2408cSBarry Smith SNESSetJacobianMatlab(). 431361b2408cSBarry Smith 431461b2408cSBarry Smith Collective on SNES 431561b2408cSBarry Smith 431661b2408cSBarry Smith Input Parameters: 431761b2408cSBarry Smith + snes - the SNES context 431861b2408cSBarry Smith . x - input vector 431961b2408cSBarry Smith . A, B - the matrices 432061b2408cSBarry Smith - ctx - user context 432161b2408cSBarry Smith 432261b2408cSBarry Smith Output Parameter: 432361b2408cSBarry Smith . flag - structure of the matrix 432461b2408cSBarry Smith 432561b2408cSBarry Smith Level: developer 432661b2408cSBarry Smith 432761b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 432861b2408cSBarry Smith 432961b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 433061b2408cSBarry Smith @*/ 43317087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 433261b2408cSBarry Smith { 433361b2408cSBarry Smith PetscErrorCode ierr; 433461b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 433561b2408cSBarry Smith int nlhs = 2,nrhs = 6; 433661b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 433761b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 433861b2408cSBarry Smith 433961b2408cSBarry Smith PetscFunctionBegin; 434061b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 434161b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 434261b2408cSBarry Smith 434361b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 434461b2408cSBarry Smith 434561b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 434661b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 434761b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 434861b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 434961b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 435061b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 435161b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 435261b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 435361b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 435461b2408cSBarry Smith prhs[5] = sctx->ctx; 4355b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 435661b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 435761b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 435861b2408cSBarry Smith mxDestroyArray(prhs[0]); 435961b2408cSBarry Smith mxDestroyArray(prhs[1]); 436061b2408cSBarry Smith mxDestroyArray(prhs[2]); 436161b2408cSBarry Smith mxDestroyArray(prhs[3]); 436261b2408cSBarry Smith mxDestroyArray(prhs[4]); 436361b2408cSBarry Smith mxDestroyArray(plhs[0]); 436461b2408cSBarry Smith mxDestroyArray(plhs[1]); 436561b2408cSBarry Smith PetscFunctionReturn(0); 436661b2408cSBarry Smith } 436761b2408cSBarry Smith 436861b2408cSBarry Smith 436961b2408cSBarry Smith #undef __FUNCT__ 437061b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 437161b2408cSBarry Smith /* 437261b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 437361b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4374e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 437561b2408cSBarry Smith 437661b2408cSBarry Smith Logically Collective on SNES 437761b2408cSBarry Smith 437861b2408cSBarry Smith Input Parameters: 437961b2408cSBarry Smith + snes - the SNES context 438061b2408cSBarry Smith . A,B - Jacobian matrices 438161b2408cSBarry Smith . func - function evaluation routine 438261b2408cSBarry Smith - ctx - user context 438361b2408cSBarry Smith 438461b2408cSBarry Smith Calling sequence of func: 438561b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 438661b2408cSBarry Smith 438761b2408cSBarry Smith 438861b2408cSBarry Smith Level: developer 438961b2408cSBarry Smith 439061b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 439161b2408cSBarry Smith 439261b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 439361b2408cSBarry Smith */ 43947087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 439561b2408cSBarry Smith { 439661b2408cSBarry Smith PetscErrorCode ierr; 439761b2408cSBarry Smith SNESMatlabContext *sctx; 439861b2408cSBarry Smith 439961b2408cSBarry Smith PetscFunctionBegin; 440061b2408cSBarry Smith /* currently sctx is memory bleed */ 440161b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 440261b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 440361b2408cSBarry Smith /* 440461b2408cSBarry Smith This should work, but it doesn't 440561b2408cSBarry Smith sctx->ctx = ctx; 440661b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 440761b2408cSBarry Smith */ 440861b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 440961b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 441061b2408cSBarry Smith PetscFunctionReturn(0); 441161b2408cSBarry Smith } 441269b4f73cSBarry Smith 4413f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4414f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4415f9eb7ae2SShri Abhyankar /* 4416f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4417f9eb7ae2SShri Abhyankar 4418f9eb7ae2SShri Abhyankar Collective on SNES 4419f9eb7ae2SShri Abhyankar 4420f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4421f9eb7ae2SShri Abhyankar @*/ 44227087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4423f9eb7ae2SShri Abhyankar { 4424f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 442548f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4426f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4427f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4428f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4429f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4430f9eb7ae2SShri Abhyankar 4431f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4432f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4433f9eb7ae2SShri Abhyankar 4434f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4435f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4436f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4437f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4438f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4439f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4440f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4441f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4442f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4443f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4444f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4445f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4446f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4447f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4448f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4449f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4450f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4451f9eb7ae2SShri Abhyankar } 4452f9eb7ae2SShri Abhyankar 4453f9eb7ae2SShri Abhyankar 4454f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4455f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4456f9eb7ae2SShri Abhyankar /* 4457e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4458f9eb7ae2SShri Abhyankar 4459f9eb7ae2SShri Abhyankar Level: developer 4460f9eb7ae2SShri Abhyankar 4461f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4462f9eb7ae2SShri Abhyankar 4463f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4464f9eb7ae2SShri Abhyankar */ 44657087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4466f9eb7ae2SShri Abhyankar { 4467f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4468f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4469f9eb7ae2SShri Abhyankar 4470f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4471f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4472f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4473f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4474f9eb7ae2SShri Abhyankar /* 4475f9eb7ae2SShri Abhyankar This should work, but it doesn't 4476f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4477f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4478f9eb7ae2SShri Abhyankar */ 4479f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4480f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4481f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4482f9eb7ae2SShri Abhyankar } 4483f9eb7ae2SShri Abhyankar 448469b4f73cSBarry Smith #endif 4485