19b94acceSBarry Smith 2b45d2f2cSJed Brown #include <petsc-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; 10f1c6b773SPeter Brune PetscLogEvent SNES_Solve, 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 16caa4e7f2SJed Brown 17caa4e7f2SJed Brown This is a legacy calling sequence, should transition to dispatching through the SNESDM. 18cab2e9ccSBarry Smith */ 19cab2e9ccSBarry Smith PetscErrorCode SNESDMComputeJacobian(SNES snes,Vec X,Mat *J,Mat *B,MatStructure *flag,void *ptr) 20cab2e9ccSBarry Smith { 21cab2e9ccSBarry Smith PetscErrorCode ierr; 22cab2e9ccSBarry Smith DM dm; 23cab2e9ccSBarry Smith 24cab2e9ccSBarry Smith PetscFunctionBegin; 25cab2e9ccSBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 26cab2e9ccSBarry Smith ierr = DMComputeJacobian(dm,X,*J,*B,flag);CHKERRQ(ierr); 27cab2e9ccSBarry Smith PetscFunctionReturn(0); 28cab2e9ccSBarry Smith } 29cab2e9ccSBarry Smith 30cab2e9ccSBarry Smith #undef __FUNCT__ 31e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged" 32e113a28aSBarry Smith /*@ 33e113a28aSBarry Smith SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged. 34e113a28aSBarry Smith 353f9fe445SBarry Smith Logically Collective on SNES 36e113a28aSBarry Smith 37e113a28aSBarry Smith Input Parameters: 38e113a28aSBarry Smith + snes - iterative context obtained from SNESCreate() 39e113a28aSBarry Smith - flg - PETSC_TRUE indicates you want the error generated 40e113a28aSBarry Smith 41e113a28aSBarry Smith Options database keys: 42e113a28aSBarry Smith . -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false) 43e113a28aSBarry Smith 44e113a28aSBarry Smith Level: intermediate 45e113a28aSBarry Smith 46e113a28aSBarry Smith Notes: 47e113a28aSBarry Smith Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve() 48e113a28aSBarry Smith to determine if it has converged. 49e113a28aSBarry Smith 50e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 51e113a28aSBarry Smith 52e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 53e113a28aSBarry Smith @*/ 547087cfbeSBarry Smith PetscErrorCode SNESSetErrorIfNotConverged(SNES snes,PetscBool flg) 55e113a28aSBarry Smith { 56e113a28aSBarry Smith PetscFunctionBegin; 57e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 58acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flg,2); 59e113a28aSBarry Smith snes->errorifnotconverged = flg; 60dd568438SSatish Balay 61e113a28aSBarry Smith PetscFunctionReturn(0); 62e113a28aSBarry Smith } 63e113a28aSBarry Smith 64e113a28aSBarry Smith #undef __FUNCT__ 65e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged" 66e113a28aSBarry Smith /*@ 67e113a28aSBarry Smith SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge? 68e113a28aSBarry Smith 69e113a28aSBarry Smith Not Collective 70e113a28aSBarry Smith 71e113a28aSBarry Smith Input Parameter: 72e113a28aSBarry Smith . snes - iterative context obtained from SNESCreate() 73e113a28aSBarry Smith 74e113a28aSBarry Smith Output Parameter: 75e113a28aSBarry Smith . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE 76e113a28aSBarry Smith 77e113a28aSBarry Smith Level: intermediate 78e113a28aSBarry Smith 79e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 80e113a28aSBarry Smith 81e113a28aSBarry Smith .seealso: SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 82e113a28aSBarry Smith @*/ 837087cfbeSBarry Smith PetscErrorCode SNESGetErrorIfNotConverged(SNES snes,PetscBool *flag) 84e113a28aSBarry Smith { 85e113a28aSBarry Smith PetscFunctionBegin; 86e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 87e113a28aSBarry Smith PetscValidPointer(flag,2); 88e113a28aSBarry Smith *flag = snes->errorifnotconverged; 89e113a28aSBarry Smith PetscFunctionReturn(0); 90e113a28aSBarry Smith } 91e113a28aSBarry Smith 92e113a28aSBarry Smith #undef __FUNCT__ 934936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError" 94e725d27bSBarry Smith /*@ 954936397dSBarry Smith SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not 964936397dSBarry Smith in the functions domain. For example, negative pressure. 974936397dSBarry Smith 983f9fe445SBarry Smith Logically Collective on SNES 994936397dSBarry Smith 1004936397dSBarry Smith Input Parameters: 1016a388c36SPeter Brune . snes - the SNES context 1024936397dSBarry Smith 10328529972SSatish Balay Level: advanced 1044936397dSBarry Smith 1054936397dSBarry Smith .keywords: SNES, view 1064936397dSBarry Smith 1074936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction() 1084936397dSBarry Smith @*/ 1097087cfbeSBarry Smith PetscErrorCode SNESSetFunctionDomainError(SNES snes) 1104936397dSBarry Smith { 1114936397dSBarry Smith PetscFunctionBegin; 1120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1134936397dSBarry Smith snes->domainerror = PETSC_TRUE; 1144936397dSBarry Smith PetscFunctionReturn(0); 1154936397dSBarry Smith } 1164936397dSBarry Smith 1176a388c36SPeter Brune 1186a388c36SPeter Brune #undef __FUNCT__ 1196a388c36SPeter Brune #define __FUNCT__ "SNESGetFunctionDomainError" 1206a388c36SPeter Brune /*@ 121c77b2880SPeter Brune SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction; 1226a388c36SPeter Brune 1236a388c36SPeter Brune Logically Collective on SNES 1246a388c36SPeter Brune 1256a388c36SPeter Brune Input Parameters: 1266a388c36SPeter Brune . snes - the SNES context 1276a388c36SPeter Brune 1286a388c36SPeter Brune Output Parameters: 1296a388c36SPeter Brune . domainerror Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise. 1306a388c36SPeter Brune 1316a388c36SPeter Brune Level: advanced 1326a388c36SPeter Brune 1336a388c36SPeter Brune .keywords: SNES, view 1346a388c36SPeter Brune 1356a388c36SPeter Brune .seealso: SNESSetFunctionDomainError, SNESComputeFunction() 1366a388c36SPeter Brune @*/ 1376a388c36SPeter Brune PetscErrorCode SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror) 1386a388c36SPeter Brune { 1396a388c36SPeter Brune PetscFunctionBegin; 1406a388c36SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1416a388c36SPeter Brune PetscValidPointer(domainerror, 2); 1426a388c36SPeter Brune *domainerror = snes->domainerror; 1436a388c36SPeter Brune PetscFunctionReturn(0); 1446a388c36SPeter Brune } 1456a388c36SPeter Brune 1466a388c36SPeter Brune 1474936397dSBarry Smith #undef __FUNCT__ 1484a2ae208SSatish Balay #define __FUNCT__ "SNESView" 1497e2c5f70SBarry Smith /*@C 1509b94acceSBarry Smith SNESView - Prints the SNES data structure. 1519b94acceSBarry Smith 1524c49b128SBarry Smith Collective on SNES 153fee21e36SBarry Smith 154c7afd0dbSLois Curfman McInnes Input Parameters: 155c7afd0dbSLois Curfman McInnes + SNES - the SNES context 156c7afd0dbSLois Curfman McInnes - viewer - visualization context 157c7afd0dbSLois Curfman McInnes 1589b94acceSBarry Smith Options Database Key: 159c8a8ba5cSLois Curfman McInnes . -snes_view - Calls SNESView() at end of SNESSolve() 1609b94acceSBarry Smith 1619b94acceSBarry Smith Notes: 1629b94acceSBarry Smith The available visualization contexts include 163b0a32e0cSBarry Smith + PETSC_VIEWER_STDOUT_SELF - standard output (default) 164b0a32e0cSBarry Smith - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 165c8a8ba5cSLois Curfman McInnes output where only the first processor opens 166c8a8ba5cSLois Curfman McInnes the file. All other processors send their 167c8a8ba5cSLois Curfman McInnes data to the first processor to print. 1689b94acceSBarry Smith 1693e081fefSLois Curfman McInnes The user can open an alternative visualization context with 170b0a32e0cSBarry Smith PetscViewerASCIIOpen() - output to a specified file. 1719b94acceSBarry Smith 17236851e7fSLois Curfman McInnes Level: beginner 17336851e7fSLois Curfman McInnes 1749b94acceSBarry Smith .keywords: SNES, view 1759b94acceSBarry Smith 176b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen() 1779b94acceSBarry Smith @*/ 1787087cfbeSBarry Smith PetscErrorCode SNESView(SNES snes,PetscViewer viewer) 1799b94acceSBarry Smith { 180fa9f3622SBarry Smith SNESKSPEW *kctx; 181dfbe8321SBarry Smith PetscErrorCode ierr; 18294b7f48cSBarry Smith KSP ksp; 1837f1410a3SPeter Brune SNESLineSearch linesearch; 184ace3abfcSBarry Smith PetscBool iascii,isstring; 1859b94acceSBarry Smith 1863a40ed3dSBarry Smith PetscFunctionBegin; 1870700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1883050cee2SBarry Smith if (!viewer) { 1897adad957SLisandro Dalcin ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 1903050cee2SBarry Smith } 1910700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 192c9780b6fSBarry Smith PetscCheckSameComm(snes,1,viewer,2); 19374679c65SBarry Smith 1942692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1952692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 19632077d6dSBarry Smith if (iascii) { 197317d6ea6SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr); 198e7788613SBarry Smith if (snes->ops->view) { 199b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 200e7788613SBarry Smith ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 201b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2020ef38995SBarry Smith } 20377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr); 204a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%G, absolute=%G, solution=%G\n", 205c60f73f4SPeter Brune snes->rtol,snes->abstol,snes->stol);CHKERRQ(ierr); 20677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr); 20777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr); 2089b94acceSBarry Smith if (snes->ksp_ewconv) { 209fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 2109b94acceSBarry Smith if (kctx) { 21177431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr); 212a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr); 213a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr); 2149b94acceSBarry Smith } 2159b94acceSBarry Smith } 216eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 217eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n");CHKERRQ(ierr); 218eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 219eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr); 220eb1f6c34SBarry Smith } 221eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 222eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n");CHKERRQ(ierr); 223eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 22442f4f86dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr); 225eb1f6c34SBarry Smith } 2260f5bd95cSBarry Smith } else if (isstring) { 227317d6ea6SBarry Smith const char *type; 228454a90a3SBarry Smith ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 229b0a32e0cSBarry Smith ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr); 23019bcc07fSBarry Smith } 23142f4f86dSBarry Smith if (snes->pc && snes->usespc) { 2324a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2334a0c5b0cSMatthew G Knepley ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr); 2344a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2354a0c5b0cSMatthew G Knepley } 2362c155ee1SBarry Smith if (snes->usesksp) { 2372c155ee1SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 238b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 23994b7f48cSBarry Smith ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 240b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2412c155ee1SBarry Smith } 2427f1410a3SPeter Brune if (snes->linesearch) { 2437f1410a3SPeter Brune ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2447f1410a3SPeter Brune ierr = SNESGetSNESLineSearch(snes, &linesearch);CHKERRQ(ierr); 2457f1410a3SPeter Brune ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr); 2467f1410a3SPeter Brune ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2477f1410a3SPeter Brune } 2483a40ed3dSBarry Smith PetscFunctionReturn(0); 2499b94acceSBarry Smith } 2509b94acceSBarry Smith 25176b2cf59SMatthew Knepley /* 25276b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 25376b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 25476b2cf59SMatthew Knepley */ 25576b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 256a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 2576849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 25876b2cf59SMatthew Knepley 259e74ef692SMatthew Knepley #undef __FUNCT__ 260e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker" 261ac226902SBarry Smith /*@C 26276b2cf59SMatthew Knepley SNESAddOptionsChecker - Adds an additional function to check for SNES options. 26376b2cf59SMatthew Knepley 26476b2cf59SMatthew Knepley Not Collective 26576b2cf59SMatthew Knepley 26676b2cf59SMatthew Knepley Input Parameter: 26776b2cf59SMatthew Knepley . snescheck - function that checks for options 26876b2cf59SMatthew Knepley 26976b2cf59SMatthew Knepley Level: developer 27076b2cf59SMatthew Knepley 27176b2cf59SMatthew Knepley .seealso: SNESSetFromOptions() 27276b2cf59SMatthew Knepley @*/ 2737087cfbeSBarry Smith PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 27476b2cf59SMatthew Knepley { 27576b2cf59SMatthew Knepley PetscFunctionBegin; 27676b2cf59SMatthew Knepley if (numberofsetfromoptions >= MAXSETFROMOPTIONS) { 277e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 27876b2cf59SMatthew Knepley } 27976b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 28076b2cf59SMatthew Knepley PetscFunctionReturn(0); 28176b2cf59SMatthew Knepley } 28276b2cf59SMatthew Knepley 2837087cfbeSBarry Smith extern PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 284aa3661deSLisandro Dalcin 285aa3661deSLisandro Dalcin #undef __FUNCT__ 286aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private" 287ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 288aa3661deSLisandro Dalcin { 289aa3661deSLisandro Dalcin Mat J; 290aa3661deSLisandro Dalcin KSP ksp; 291aa3661deSLisandro Dalcin PC pc; 292ace3abfcSBarry Smith PetscBool match; 293aa3661deSLisandro Dalcin PetscErrorCode ierr; 294aa3661deSLisandro Dalcin 295aa3661deSLisandro Dalcin PetscFunctionBegin; 2960700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 297aa3661deSLisandro Dalcin 29898613b67SLisandro Dalcin if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 29998613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 30098613b67SLisandro Dalcin ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr); 30198613b67SLisandro Dalcin } 30298613b67SLisandro Dalcin 303aa3661deSLisandro Dalcin if (version == 1) { 304aa3661deSLisandro Dalcin ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 30598613b67SLisandro Dalcin ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 3069c6ac3b3SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 307aa3661deSLisandro Dalcin } else if (version == 2) { 308e32f2f54SBarry Smith if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 30982a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 310aa3661deSLisandro Dalcin ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr); 311aa3661deSLisandro Dalcin #else 312e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)"); 313aa3661deSLisandro Dalcin #endif 314a8248277SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2"); 315aa3661deSLisandro Dalcin 316aa3661deSLisandro Dalcin ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr); 317d3462f78SMatthew Knepley if (hasOperator) { 318aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 319aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 320aa3661deSLisandro Dalcin ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 321aa3661deSLisandro Dalcin } else { 322aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 323aa3661deSLisandro Dalcin provided preconditioner matrix with the default matrix free version. */ 3246cab3a1bSJed Brown void *functx; 3256cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 3266cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr); 327aa3661deSLisandro Dalcin /* Force no preconditioner */ 328aa3661deSLisandro Dalcin ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 329aa3661deSLisandro Dalcin ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 330aa3661deSLisandro Dalcin ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr); 331aa3661deSLisandro Dalcin if (!match) { 332aa3661deSLisandro Dalcin ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 333aa3661deSLisandro Dalcin ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 334aa3661deSLisandro Dalcin } 335aa3661deSLisandro Dalcin } 3366bf464f9SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 337aa3661deSLisandro Dalcin PetscFunctionReturn(0); 338aa3661deSLisandro Dalcin } 339aa3661deSLisandro Dalcin 3404a2ae208SSatish Balay #undef __FUNCT__ 341*dfe15315SJed Brown #define __FUNCT__ "DMRestrictHook_SNESVecSol" 342*dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx) 343*dfe15315SJed Brown { 344*dfe15315SJed Brown SNES snes = (SNES)ctx; 345*dfe15315SJed Brown PetscErrorCode ierr; 346*dfe15315SJed Brown Vec Xfine,Xfine_named = PETSC_NULL,Xcoarse; 347*dfe15315SJed Brown 348*dfe15315SJed Brown PetscFunctionBegin; 349*dfe15315SJed Brown if (dmfine == snes->dm) Xfine = snes->vec_sol; 350*dfe15315SJed Brown else { 351*dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr); 352*dfe15315SJed Brown Xfine = Xfine_named; 353*dfe15315SJed Brown } 354*dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 355*dfe15315SJed Brown ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr); 356*dfe15315SJed Brown ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr); 357*dfe15315SJed Brown ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 358*dfe15315SJed Brown if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);} 359*dfe15315SJed Brown PetscFunctionReturn(0); 360*dfe15315SJed Brown } 361*dfe15315SJed Brown 362*dfe15315SJed Brown #undef __FUNCT__ 363caa4e7f2SJed Brown #define __FUNCT__ "KSPComputeOperators_SNES" 364caa4e7f2SJed Brown static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,MatStructure *mstruct,void *ctx) 365caa4e7f2SJed Brown { 366caa4e7f2SJed Brown SNES snes = (SNES)ctx; 367caa4e7f2SJed Brown PetscErrorCode ierr; 368caa4e7f2SJed Brown Mat Asave = A,Bsave = B; 369*dfe15315SJed Brown Vec X,Xnamed = PETSC_NULL; 370*dfe15315SJed Brown DM dmsave; 371caa4e7f2SJed Brown 372caa4e7f2SJed Brown PetscFunctionBegin; 373*dfe15315SJed Brown dmsave = snes->dm; 374*dfe15315SJed Brown ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr); 375*dfe15315SJed Brown if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */ 376*dfe15315SJed Brown else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ 377*dfe15315SJed Brown ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 378*dfe15315SJed Brown X = Xnamed; 379*dfe15315SJed Brown } 380*dfe15315SJed Brown ierr = SNESComputeJacobian(snes,X,&A,&B,mstruct);CHKERRQ(ierr); 381caa4e7f2SJed Brown if (A != Asave || B != Bsave) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"No support for changing matrices at this time"); 382*dfe15315SJed Brown if (Xnamed) { 383*dfe15315SJed Brown ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 384*dfe15315SJed Brown } 385*dfe15315SJed Brown snes->dm = dmsave; 386caa4e7f2SJed Brown PetscFunctionReturn(0); 387caa4e7f2SJed Brown } 388caa4e7f2SJed Brown 389caa4e7f2SJed Brown #undef __FUNCT__ 3906cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices" 3916cab3a1bSJed Brown /*@ 3926cab3a1bSJed Brown SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX() 3936cab3a1bSJed Brown 3946cab3a1bSJed Brown Collective 3956cab3a1bSJed Brown 3966cab3a1bSJed Brown Input Arguments: 3976cab3a1bSJed Brown . snes - snes to configure 3986cab3a1bSJed Brown 3996cab3a1bSJed Brown Level: developer 4006cab3a1bSJed Brown 4016cab3a1bSJed Brown .seealso: SNESSetUp() 4026cab3a1bSJed Brown @*/ 4036cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes) 4046cab3a1bSJed Brown { 4056cab3a1bSJed Brown PetscErrorCode ierr; 4066cab3a1bSJed Brown DM dm; 4076cab3a1bSJed Brown SNESDM sdm; 4086cab3a1bSJed Brown 4096cab3a1bSJed Brown PetscFunctionBegin; 4106cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4116cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 412caa4e7f2SJed Brown if (!sdm->computejacobian) { 4136cab3a1bSJed Brown Mat J,B; 4146cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 4156cab3a1bSJed Brown if (snes->mf_operator) { 4166cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4176cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4186cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4196cab3a1bSJed Brown } else { 4206cab3a1bSJed Brown J = B; 4216cab3a1bSJed Brown ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr); 4226cab3a1bSJed Brown } 4236cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr); 4246cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 4256cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 4266cab3a1bSJed Brown } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) { 4276cab3a1bSJed Brown Mat J; 4286cab3a1bSJed Brown void *functx; 4296cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4306cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4316cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4326cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 4336cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr); 4346cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 435caa4e7f2SJed Brown } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 4366cab3a1bSJed Brown Mat J,B; 4376cab3a1bSJed Brown void *functx; 4386cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4396cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4406cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4416cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 4426cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 4436cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,functx);CHKERRQ(ierr); 4446cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 4456cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 446caa4e7f2SJed Brown } else if (!snes->jacobian_pre) { 4476cab3a1bSJed Brown Mat J,B; 4486cab3a1bSJed Brown J = snes->jacobian; 4496cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 4506cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 4516cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 4526cab3a1bSJed Brown } 453caa4e7f2SJed Brown { 454caa4e7f2SJed Brown PetscBool flg = PETSC_FALSE; 455caa4e7f2SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_kspcompute",&flg,PETSC_NULL);CHKERRQ(ierr); 456caa4e7f2SJed Brown if (flg) { /* Plan to transition to this model */ 457caa4e7f2SJed Brown KSP ksp; 458caa4e7f2SJed Brown ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 459caa4e7f2SJed Brown ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr); 460*dfe15315SJed Brown ierr = DMCoarsenHookAdd(snes->dm,PETSC_NULL,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 461caa4e7f2SJed Brown } 462caa4e7f2SJed Brown } 4636cab3a1bSJed Brown PetscFunctionReturn(0); 4646cab3a1bSJed Brown } 4656cab3a1bSJed Brown 4666cab3a1bSJed Brown #undef __FUNCT__ 4674a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions" 4689b94acceSBarry Smith /*@ 46994b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 4709b94acceSBarry Smith 471c7afd0dbSLois Curfman McInnes Collective on SNES 472c7afd0dbSLois Curfman McInnes 4739b94acceSBarry Smith Input Parameter: 4749b94acceSBarry Smith . snes - the SNES context 4759b94acceSBarry Smith 47636851e7fSLois Curfman McInnes Options Database Keys: 477ea630c6eSPeter Brune + -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas 47882738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 47982738288SBarry Smith of the change in the solution between steps 48070441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 481b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 482b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 483b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 4844839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 485ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 486a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 487e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 488b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 4892492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 49082738288SBarry Smith solver; hence iterations will continue until max_it 4911fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 49282738288SBarry Smith of convergence test 493e8105e01SRichard Katz . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 494e8105e01SRichard Katz filename given prints to stdout 495a6570f20SBarry Smith . -snes_monitor_solution - plots solution at each iteration 496a6570f20SBarry Smith . -snes_monitor_residual - plots residual (not its norm) at each iteration 497a6570f20SBarry Smith . -snes_monitor_solution_update - plots update to solution at each iteration 498a6570f20SBarry Smith . -snes_monitor_draw - plots residual norm at each iteration 499e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 5005968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 501fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 50282738288SBarry Smith 50382738288SBarry Smith Options Database for Eisenstat-Walker method: 504fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 5054b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 50636851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 50736851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 50836851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 50936851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 51036851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 51136851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 51282738288SBarry Smith 51311ca99fdSLois Curfman McInnes Notes: 51411ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 5150598bfebSBarry Smith the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>. 51683e2fdc7SBarry Smith 51736851e7fSLois Curfman McInnes Level: beginner 51836851e7fSLois Curfman McInnes 5199b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 5209b94acceSBarry Smith 52169ed319cSSatish Balay .seealso: SNESSetOptionsPrefix() 5229b94acceSBarry Smith @*/ 5237087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 5249b94acceSBarry Smith { 525872b6db9SPeter Brune PetscBool flg,mf,mf_operator,pcset; 526efd51863SBarry Smith PetscInt i,indx,lag,mf_version,grids; 527aa3661deSLisandro Dalcin MatStructure matflag; 52885385478SLisandro Dalcin const char *deft = SNESLS; 52985385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 53085385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 531e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 53251e86f29SPeter Brune const char *optionsprefix; 533649052a6SBarry Smith PetscViewer monviewer; 53485385478SLisandro Dalcin PetscErrorCode ierr; 5359b94acceSBarry Smith 5363a40ed3dSBarry Smith PetscFunctionBegin; 5370700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 538ca161407SBarry Smith 539186905e3SBarry Smith if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 5403194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 5417adad957SLisandro Dalcin if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; } 542b0a32e0cSBarry Smith ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 543d64ed03dSBarry Smith if (flg) { 544186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 5457adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 546186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 547d64ed03dSBarry Smith } 54890d69ab7SBarry Smith /* not used here, but called so will go into help messaage */ 549909c8a9fSBarry Smith ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 55093c39befSBarry Smith 551c60f73f4SPeter Brune ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr); 55257034d6fSHong Zhang ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 553186905e3SBarry Smith 55457034d6fSHong Zhang ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 555b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 556b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 55750ffb88aSMatthew Knepley ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 558ddf469c8SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr); 559acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr); 56085385478SLisandro Dalcin 561a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 562a8054027SBarry Smith if (flg) { 563a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 564a8054027SBarry Smith } 565e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 566e35cf81dSBarry Smith if (flg) { 567e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 568e35cf81dSBarry Smith } 569efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 570efd51863SBarry Smith if (flg) { 571efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 572efd51863SBarry Smith } 573a8054027SBarry Smith 57485385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 57585385478SLisandro Dalcin if (flg) { 57685385478SLisandro Dalcin switch (indx) { 5777f7931b9SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 5787f7931b9SBarry Smith case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 57985385478SLisandro Dalcin } 58085385478SLisandro Dalcin } 58185385478SLisandro Dalcin 582acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr); 583186905e3SBarry Smith 58485385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 58585385478SLisandro Dalcin 586acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 587186905e3SBarry Smith 588fa9f3622SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 589fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 590fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 591fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 592fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 593fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 594fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 595186905e3SBarry Smith 59690d69ab7SBarry Smith flg = PETSC_FALSE; 597acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 598a6570f20SBarry Smith if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 599eabae89aSBarry Smith 600a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 601e8105e01SRichard Katz if (flg) { 602649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 603649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 604e8105e01SRichard Katz } 605eabae89aSBarry Smith 606b271bb04SBarry Smith ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 607b271bb04SBarry Smith if (flg) { 608b271bb04SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 609b271bb04SBarry Smith } 610b271bb04SBarry Smith 611a6570f20SBarry Smith ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 612eabae89aSBarry Smith if (flg) { 613649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 614f1bef1bcSMatthew Knepley ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 615e8105e01SRichard Katz } 616eabae89aSBarry Smith 617a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 618eabae89aSBarry Smith if (flg) { 619649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 620649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 621eabae89aSBarry Smith } 622eabae89aSBarry Smith 6235180491cSLisandro Dalcin ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 6245180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 6255180491cSLisandro Dalcin 62690d69ab7SBarry Smith flg = PETSC_FALSE; 627acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 628a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 62990d69ab7SBarry Smith flg = PETSC_FALSE; 630acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 631a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 63290d69ab7SBarry Smith flg = PETSC_FALSE; 633acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 634a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 63590d69ab7SBarry Smith flg = PETSC_FALSE; 636acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 637a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 63890d69ab7SBarry Smith flg = PETSC_FALSE; 639acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 640b271bb04SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 641e24b481bSBarry Smith 64290d69ab7SBarry Smith flg = PETSC_FALSE; 643acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 6444b27c08aSLois Curfman McInnes if (flg) { 6456cab3a1bSJed Brown void *functx; 6466cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 6476cab3a1bSJed Brown ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr); 648ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 6499b94acceSBarry Smith } 650639f9d9dSBarry Smith 651aa3661deSLisandro Dalcin mf = mf_operator = PETSC_FALSE; 652aa3661deSLisandro Dalcin flg = PETSC_FALSE; 653acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr); 654a8248277SBarry Smith if (flg && mf_operator) { 655a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 656a8248277SBarry Smith mf = PETSC_TRUE; 657a8248277SBarry Smith } 658aa3661deSLisandro Dalcin flg = PETSC_FALSE; 659acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr); 660aa3661deSLisandro Dalcin if (!flg && mf_operator) mf = PETSC_TRUE; 661aa3661deSLisandro Dalcin mf_version = 1; 662aa3661deSLisandro Dalcin ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr); 663aa3661deSLisandro Dalcin 664d28543b3SPeter Brune 66589b92e6fSPeter Brune /* GS Options */ 66689b92e6fSPeter Brune ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr); 66789b92e6fSPeter Brune 66876b2cf59SMatthew Knepley for(i = 0; i < numberofsetfromoptions; i++) { 66976b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 67076b2cf59SMatthew Knepley } 67176b2cf59SMatthew Knepley 672e7788613SBarry Smith if (snes->ops->setfromoptions) { 673e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 674639f9d9dSBarry Smith } 6755d973c19SBarry Smith 6765d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 6775d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 678b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 6794bbc92c1SBarry Smith 680aa3661deSLisandro Dalcin if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 6811cee3971SBarry Smith 6821cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 683aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 684aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 68585385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 68693993e2dSLois Curfman McInnes 6879e764e56SPeter Brune if (!snes->linesearch) { 688f1c6b773SPeter Brune ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 6899e764e56SPeter Brune } 690f1c6b773SPeter Brune ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr); 6919e764e56SPeter Brune 69251e86f29SPeter Brune /* if someone has set the SNES PC type, create it. */ 69351e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 69451e86f29SPeter Brune ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 69551e86f29SPeter Brune if (pcset && (!snes->pc)) { 69651e86f29SPeter Brune ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr); 69751e86f29SPeter Brune } 6984a0c5b0cSMatthew G Knepley if (snes->pc) { 699fde0ff24SPeter Brune ierr = SNESSetOptionsPrefix(snes->pc, optionsprefix);CHKERRQ(ierr); 700fde0ff24SPeter Brune ierr = SNESAppendOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr); 7014a0c5b0cSMatthew G Knepley ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 70288976e71SPeter Brune /* default to 1 iteration */ 70388976e71SPeter Brune ierr = SNESSetTolerances(snes->pc, snes->pc->abstol, snes->pc->rtol, snes->pc->stol, 1, snes->pc->max_funcs);CHKERRQ(ierr); 7044a0c5b0cSMatthew G Knepley ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 7054a0c5b0cSMatthew G Knepley } 7063a40ed3dSBarry Smith PetscFunctionReturn(0); 7079b94acceSBarry Smith } 7089b94acceSBarry Smith 709d25893d9SBarry Smith #undef __FUNCT__ 710d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 711d25893d9SBarry Smith /*@ 712d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 713d25893d9SBarry Smith the nonlinear solvers. 714d25893d9SBarry Smith 715d25893d9SBarry Smith Logically Collective on SNES 716d25893d9SBarry Smith 717d25893d9SBarry Smith Input Parameters: 718d25893d9SBarry Smith + snes - the SNES context 719d25893d9SBarry Smith . compute - function to compute the context 720d25893d9SBarry Smith - destroy - function to destroy the context 721d25893d9SBarry Smith 722d25893d9SBarry Smith Level: intermediate 723d25893d9SBarry Smith 724d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 725d25893d9SBarry Smith 726d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 727d25893d9SBarry Smith @*/ 728d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 729d25893d9SBarry Smith { 730d25893d9SBarry Smith PetscFunctionBegin; 731d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 732d25893d9SBarry Smith snes->ops->usercompute = compute; 733d25893d9SBarry Smith snes->ops->userdestroy = destroy; 734d25893d9SBarry Smith PetscFunctionReturn(0); 735d25893d9SBarry Smith } 736a847f771SSatish Balay 7374a2ae208SSatish Balay #undef __FUNCT__ 7384a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 739b07ff414SBarry Smith /*@ 7409b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 7419b94acceSBarry Smith the nonlinear solvers. 7429b94acceSBarry Smith 7433f9fe445SBarry Smith Logically Collective on SNES 744fee21e36SBarry Smith 745c7afd0dbSLois Curfman McInnes Input Parameters: 746c7afd0dbSLois Curfman McInnes + snes - the SNES context 747c7afd0dbSLois Curfman McInnes - usrP - optional user context 748c7afd0dbSLois Curfman McInnes 74936851e7fSLois Curfman McInnes Level: intermediate 75036851e7fSLois Curfman McInnes 7519b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 7529b94acceSBarry Smith 753d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext() 7549b94acceSBarry Smith @*/ 7557087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 7569b94acceSBarry Smith { 7571b2093e4SBarry Smith PetscErrorCode ierr; 758b07ff414SBarry Smith KSP ksp; 7591b2093e4SBarry Smith 7603a40ed3dSBarry Smith PetscFunctionBegin; 7610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 762b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 763b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 7649b94acceSBarry Smith snes->user = usrP; 7653a40ed3dSBarry Smith PetscFunctionReturn(0); 7669b94acceSBarry Smith } 76774679c65SBarry Smith 7684a2ae208SSatish Balay #undef __FUNCT__ 7694a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 770b07ff414SBarry Smith /*@ 7719b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 7729b94acceSBarry Smith nonlinear solvers. 7739b94acceSBarry Smith 774c7afd0dbSLois Curfman McInnes Not Collective 775c7afd0dbSLois Curfman McInnes 7769b94acceSBarry Smith Input Parameter: 7779b94acceSBarry Smith . snes - SNES context 7789b94acceSBarry Smith 7799b94acceSBarry Smith Output Parameter: 7809b94acceSBarry Smith . usrP - user context 7819b94acceSBarry Smith 78236851e7fSLois Curfman McInnes Level: intermediate 78336851e7fSLois Curfman McInnes 7849b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 7859b94acceSBarry Smith 7869b94acceSBarry Smith .seealso: SNESSetApplicationContext() 7879b94acceSBarry Smith @*/ 788e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 7899b94acceSBarry Smith { 7903a40ed3dSBarry Smith PetscFunctionBegin; 7910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 792e71120c6SJed Brown *(void**)usrP = snes->user; 7933a40ed3dSBarry Smith PetscFunctionReturn(0); 7949b94acceSBarry Smith } 79574679c65SBarry Smith 7964a2ae208SSatish Balay #undef __FUNCT__ 7974a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 7989b94acceSBarry Smith /*@ 799c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 800c8228a4eSBarry Smith at this time. 8019b94acceSBarry Smith 802c7afd0dbSLois Curfman McInnes Not Collective 803c7afd0dbSLois Curfman McInnes 8049b94acceSBarry Smith Input Parameter: 8059b94acceSBarry Smith . snes - SNES context 8069b94acceSBarry Smith 8079b94acceSBarry Smith Output Parameter: 8089b94acceSBarry Smith . iter - iteration number 8099b94acceSBarry Smith 810c8228a4eSBarry Smith Notes: 811c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 812c8228a4eSBarry Smith 813c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 81408405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 81508405cd6SLois Curfman McInnes .vb 81608405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 81708405cd6SLois Curfman McInnes if (!(it % 2)) { 81808405cd6SLois Curfman McInnes [compute Jacobian here] 81908405cd6SLois Curfman McInnes } 82008405cd6SLois Curfman McInnes .ve 821c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 82208405cd6SLois Curfman McInnes recomputed every second SNES iteration. 823c8228a4eSBarry Smith 82436851e7fSLois Curfman McInnes Level: intermediate 82536851e7fSLois Curfman McInnes 8262b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 8272b668275SBarry Smith 828b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 8299b94acceSBarry Smith @*/ 8307087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 8319b94acceSBarry Smith { 8323a40ed3dSBarry Smith PetscFunctionBegin; 8330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8344482741eSBarry Smith PetscValidIntPointer(iter,2); 8359b94acceSBarry Smith *iter = snes->iter; 8363a40ed3dSBarry Smith PetscFunctionReturn(0); 8379b94acceSBarry Smith } 83874679c65SBarry Smith 8394a2ae208SSatish Balay #undef __FUNCT__ 840360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber" 841360c497dSPeter Brune /*@ 842360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 843360c497dSPeter Brune 844360c497dSPeter Brune Not Collective 845360c497dSPeter Brune 846360c497dSPeter Brune Input Parameter: 847360c497dSPeter Brune . snes - SNES context 848360c497dSPeter Brune . iter - iteration number 849360c497dSPeter Brune 850360c497dSPeter Brune Level: developer 851360c497dSPeter Brune 852360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number, 853360c497dSPeter Brune 854360c497dSPeter Brune .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 855360c497dSPeter Brune @*/ 856360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 857360c497dSPeter Brune { 858360c497dSPeter Brune PetscErrorCode ierr; 859360c497dSPeter Brune 860360c497dSPeter Brune PetscFunctionBegin; 861360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 862360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 863360c497dSPeter Brune snes->iter = iter; 864360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 865360c497dSPeter Brune PetscFunctionReturn(0); 866360c497dSPeter Brune } 867360c497dSPeter Brune 868360c497dSPeter Brune #undef __FUNCT__ 8694a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 8709b94acceSBarry Smith /*@ 8719b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 8729b94acceSBarry Smith with SNESSSetFunction(). 8739b94acceSBarry Smith 874c7afd0dbSLois Curfman McInnes Collective on SNES 875c7afd0dbSLois Curfman McInnes 8769b94acceSBarry Smith Input Parameter: 8779b94acceSBarry Smith . snes - SNES context 8789b94acceSBarry Smith 8799b94acceSBarry Smith Output Parameter: 8809b94acceSBarry Smith . fnorm - 2-norm of function 8819b94acceSBarry Smith 88236851e7fSLois Curfman McInnes Level: intermediate 88336851e7fSLois Curfman McInnes 8849b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 885a86d99e1SLois Curfman McInnes 886b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 8879b94acceSBarry Smith @*/ 8887087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 8899b94acceSBarry Smith { 8903a40ed3dSBarry Smith PetscFunctionBegin; 8910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8924482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 8939b94acceSBarry Smith *fnorm = snes->norm; 8943a40ed3dSBarry Smith PetscFunctionReturn(0); 8959b94acceSBarry Smith } 89674679c65SBarry Smith 897360c497dSPeter Brune 898360c497dSPeter Brune #undef __FUNCT__ 899360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm" 900360c497dSPeter Brune /*@ 901360c497dSPeter Brune SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm(). 902360c497dSPeter Brune 903360c497dSPeter Brune Collective on SNES 904360c497dSPeter Brune 905360c497dSPeter Brune Input Parameter: 906360c497dSPeter Brune . snes - SNES context 907360c497dSPeter Brune . fnorm - 2-norm of function 908360c497dSPeter Brune 909360c497dSPeter Brune Level: developer 910360c497dSPeter Brune 911360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm 912360c497dSPeter Brune 913360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm(). 914360c497dSPeter Brune @*/ 915360c497dSPeter Brune PetscErrorCode SNESSetFunctionNorm(SNES snes,PetscReal fnorm) 916360c497dSPeter Brune { 917360c497dSPeter Brune 918360c497dSPeter Brune PetscErrorCode ierr; 919360c497dSPeter Brune 920360c497dSPeter Brune PetscFunctionBegin; 921360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 922360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 923360c497dSPeter Brune snes->norm = fnorm; 924360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 925360c497dSPeter Brune PetscFunctionReturn(0); 926360c497dSPeter Brune } 927360c497dSPeter Brune 9284a2ae208SSatish Balay #undef __FUNCT__ 929b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 9309b94acceSBarry Smith /*@ 931b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 9329b94acceSBarry Smith attempted by the nonlinear solver. 9339b94acceSBarry Smith 934c7afd0dbSLois Curfman McInnes Not Collective 935c7afd0dbSLois Curfman McInnes 9369b94acceSBarry Smith Input Parameter: 9379b94acceSBarry Smith . snes - SNES context 9389b94acceSBarry Smith 9399b94acceSBarry Smith Output Parameter: 9409b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 9419b94acceSBarry Smith 942c96a6f78SLois Curfman McInnes Notes: 943c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 944c96a6f78SLois Curfman McInnes 94536851e7fSLois Curfman McInnes Level: intermediate 94636851e7fSLois Curfman McInnes 9479b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 94858ebbce7SBarry Smith 949e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 95058ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 9519b94acceSBarry Smith @*/ 9527087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 9539b94acceSBarry Smith { 9543a40ed3dSBarry Smith PetscFunctionBegin; 9550700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9564482741eSBarry Smith PetscValidIntPointer(nfails,2); 95750ffb88aSMatthew Knepley *nfails = snes->numFailures; 95850ffb88aSMatthew Knepley PetscFunctionReturn(0); 95950ffb88aSMatthew Knepley } 96050ffb88aSMatthew Knepley 96150ffb88aSMatthew Knepley #undef __FUNCT__ 962b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 96350ffb88aSMatthew Knepley /*@ 964b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 96550ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 96650ffb88aSMatthew Knepley 96750ffb88aSMatthew Knepley Not Collective 96850ffb88aSMatthew Knepley 96950ffb88aSMatthew Knepley Input Parameters: 97050ffb88aSMatthew Knepley + snes - SNES context 97150ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 97250ffb88aSMatthew Knepley 97350ffb88aSMatthew Knepley Level: intermediate 97450ffb88aSMatthew Knepley 97550ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 97658ebbce7SBarry Smith 977e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 97858ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 97950ffb88aSMatthew Knepley @*/ 9807087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 98150ffb88aSMatthew Knepley { 98250ffb88aSMatthew Knepley PetscFunctionBegin; 9830700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 98450ffb88aSMatthew Knepley snes->maxFailures = maxFails; 98550ffb88aSMatthew Knepley PetscFunctionReturn(0); 98650ffb88aSMatthew Knepley } 98750ffb88aSMatthew Knepley 98850ffb88aSMatthew Knepley #undef __FUNCT__ 989b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 99050ffb88aSMatthew Knepley /*@ 991b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 99250ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 99350ffb88aSMatthew Knepley 99450ffb88aSMatthew Knepley Not Collective 99550ffb88aSMatthew Knepley 99650ffb88aSMatthew Knepley Input Parameter: 99750ffb88aSMatthew Knepley . snes - SNES context 99850ffb88aSMatthew Knepley 99950ffb88aSMatthew Knepley Output Parameter: 100050ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 100150ffb88aSMatthew Knepley 100250ffb88aSMatthew Knepley Level: intermediate 100350ffb88aSMatthew Knepley 100450ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 100558ebbce7SBarry Smith 1006e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 100758ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 100858ebbce7SBarry Smith 100950ffb88aSMatthew Knepley @*/ 10107087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 101150ffb88aSMatthew Knepley { 101250ffb88aSMatthew Knepley PetscFunctionBegin; 10130700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10144482741eSBarry Smith PetscValidIntPointer(maxFails,2); 101550ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 10163a40ed3dSBarry Smith PetscFunctionReturn(0); 10179b94acceSBarry Smith } 1018a847f771SSatish Balay 10194a2ae208SSatish Balay #undef __FUNCT__ 10202541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 10212541af92SBarry Smith /*@ 10222541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 10232541af92SBarry Smith done by SNES. 10242541af92SBarry Smith 10252541af92SBarry Smith Not Collective 10262541af92SBarry Smith 10272541af92SBarry Smith Input Parameter: 10282541af92SBarry Smith . snes - SNES context 10292541af92SBarry Smith 10302541af92SBarry Smith Output Parameter: 10312541af92SBarry Smith . nfuncs - number of evaluations 10322541af92SBarry Smith 10332541af92SBarry Smith Level: intermediate 10342541af92SBarry Smith 10352541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 103658ebbce7SBarry Smith 1037e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 10382541af92SBarry Smith @*/ 10397087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 10402541af92SBarry Smith { 10412541af92SBarry Smith PetscFunctionBegin; 10420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10432541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 10442541af92SBarry Smith *nfuncs = snes->nfuncs; 10452541af92SBarry Smith PetscFunctionReturn(0); 10462541af92SBarry Smith } 10472541af92SBarry Smith 10482541af92SBarry Smith #undef __FUNCT__ 10493d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 10503d4c4710SBarry Smith /*@ 10513d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 10523d4c4710SBarry Smith linear solvers. 10533d4c4710SBarry Smith 10543d4c4710SBarry Smith Not Collective 10553d4c4710SBarry Smith 10563d4c4710SBarry Smith Input Parameter: 10573d4c4710SBarry Smith . snes - SNES context 10583d4c4710SBarry Smith 10593d4c4710SBarry Smith Output Parameter: 10603d4c4710SBarry Smith . nfails - number of failed solves 10613d4c4710SBarry Smith 10623d4c4710SBarry Smith Notes: 10633d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 10643d4c4710SBarry Smith 10653d4c4710SBarry Smith Level: intermediate 10663d4c4710SBarry Smith 10673d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 106858ebbce7SBarry Smith 1069e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 10703d4c4710SBarry Smith @*/ 10717087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 10723d4c4710SBarry Smith { 10733d4c4710SBarry Smith PetscFunctionBegin; 10740700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10753d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 10763d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 10773d4c4710SBarry Smith PetscFunctionReturn(0); 10783d4c4710SBarry Smith } 10793d4c4710SBarry Smith 10803d4c4710SBarry Smith #undef __FUNCT__ 10813d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 10823d4c4710SBarry Smith /*@ 10833d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 10843d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 10853d4c4710SBarry Smith 10863f9fe445SBarry Smith Logically Collective on SNES 10873d4c4710SBarry Smith 10883d4c4710SBarry Smith Input Parameters: 10893d4c4710SBarry Smith + snes - SNES context 10903d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 10913d4c4710SBarry Smith 10923d4c4710SBarry Smith Level: intermediate 10933d4c4710SBarry Smith 1094a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 10953d4c4710SBarry Smith 10963d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 10973d4c4710SBarry Smith 109858ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 10993d4c4710SBarry Smith @*/ 11007087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 11013d4c4710SBarry Smith { 11023d4c4710SBarry Smith PetscFunctionBegin; 11030700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1104c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 11053d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 11063d4c4710SBarry Smith PetscFunctionReturn(0); 11073d4c4710SBarry Smith } 11083d4c4710SBarry Smith 11093d4c4710SBarry Smith #undef __FUNCT__ 11103d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 11113d4c4710SBarry Smith /*@ 11123d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 11133d4c4710SBarry Smith are allowed before SNES terminates 11143d4c4710SBarry Smith 11153d4c4710SBarry Smith Not Collective 11163d4c4710SBarry Smith 11173d4c4710SBarry Smith Input Parameter: 11183d4c4710SBarry Smith . snes - SNES context 11193d4c4710SBarry Smith 11203d4c4710SBarry Smith Output Parameter: 11213d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 11223d4c4710SBarry Smith 11233d4c4710SBarry Smith Level: intermediate 11243d4c4710SBarry Smith 11253d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 11263d4c4710SBarry Smith 11273d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 11283d4c4710SBarry Smith 1129e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 11303d4c4710SBarry Smith @*/ 11317087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 11323d4c4710SBarry Smith { 11333d4c4710SBarry Smith PetscFunctionBegin; 11340700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11353d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 11363d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 11373d4c4710SBarry Smith PetscFunctionReturn(0); 11383d4c4710SBarry Smith } 11393d4c4710SBarry Smith 11403d4c4710SBarry Smith #undef __FUNCT__ 1141b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 1142c96a6f78SLois Curfman McInnes /*@ 1143b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1144c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1145c96a6f78SLois Curfman McInnes 1146c7afd0dbSLois Curfman McInnes Not Collective 1147c7afd0dbSLois Curfman McInnes 1148c96a6f78SLois Curfman McInnes Input Parameter: 1149c96a6f78SLois Curfman McInnes . snes - SNES context 1150c96a6f78SLois Curfman McInnes 1151c96a6f78SLois Curfman McInnes Output Parameter: 1152c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1153c96a6f78SLois Curfman McInnes 1154c96a6f78SLois Curfman McInnes Notes: 1155c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1156c96a6f78SLois Curfman McInnes 115736851e7fSLois Curfman McInnes Level: intermediate 115836851e7fSLois Curfman McInnes 1159c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 11602b668275SBarry Smith 11618c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 1162c96a6f78SLois Curfman McInnes @*/ 11637087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 1164c96a6f78SLois Curfman McInnes { 11653a40ed3dSBarry Smith PetscFunctionBegin; 11660700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11674482741eSBarry Smith PetscValidIntPointer(lits,2); 1168c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 11693a40ed3dSBarry Smith PetscFunctionReturn(0); 1170c96a6f78SLois Curfman McInnes } 1171c96a6f78SLois Curfman McInnes 11724a2ae208SSatish Balay #undef __FUNCT__ 117394b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 117452baeb72SSatish Balay /*@ 117594b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 11769b94acceSBarry Smith 117794b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 1178c7afd0dbSLois Curfman McInnes 11799b94acceSBarry Smith Input Parameter: 11809b94acceSBarry Smith . snes - the SNES context 11819b94acceSBarry Smith 11829b94acceSBarry Smith Output Parameter: 118394b7f48cSBarry Smith . ksp - the KSP context 11849b94acceSBarry Smith 11859b94acceSBarry Smith Notes: 118694b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 11879b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 11882999313aSBarry Smith PC contexts as well. 11899b94acceSBarry Smith 119036851e7fSLois Curfman McInnes Level: beginner 119136851e7fSLois Curfman McInnes 119294b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 11939b94acceSBarry Smith 11942999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 11959b94acceSBarry Smith @*/ 11967087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 11979b94acceSBarry Smith { 11981cee3971SBarry Smith PetscErrorCode ierr; 11991cee3971SBarry Smith 12003a40ed3dSBarry Smith PetscFunctionBegin; 12010700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12024482741eSBarry Smith PetscValidPointer(ksp,2); 12031cee3971SBarry Smith 12041cee3971SBarry Smith if (!snes->ksp) { 12051cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 12061cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 12071cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 12081cee3971SBarry Smith } 120994b7f48cSBarry Smith *ksp = snes->ksp; 12103a40ed3dSBarry Smith PetscFunctionReturn(0); 12119b94acceSBarry Smith } 121282bf6240SBarry Smith 12134a2ae208SSatish Balay #undef __FUNCT__ 12142999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 12152999313aSBarry Smith /*@ 12162999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 12172999313aSBarry Smith 12182999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 12192999313aSBarry Smith 12202999313aSBarry Smith Input Parameters: 12212999313aSBarry Smith + snes - the SNES context 12222999313aSBarry Smith - ksp - the KSP context 12232999313aSBarry Smith 12242999313aSBarry Smith Notes: 12252999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 12262999313aSBarry Smith so this routine is rarely needed. 12272999313aSBarry Smith 12282999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 12292999313aSBarry Smith decreased by one. 12302999313aSBarry Smith 12312999313aSBarry Smith Level: developer 12322999313aSBarry Smith 12332999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 12342999313aSBarry Smith 12352999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 12362999313aSBarry Smith @*/ 12377087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 12382999313aSBarry Smith { 12392999313aSBarry Smith PetscErrorCode ierr; 12402999313aSBarry Smith 12412999313aSBarry Smith PetscFunctionBegin; 12420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12430700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 12442999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 12457dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1246906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 12472999313aSBarry Smith snes->ksp = ksp; 12482999313aSBarry Smith PetscFunctionReturn(0); 12492999313aSBarry Smith } 12502999313aSBarry Smith 12517adad957SLisandro Dalcin #if 0 12522999313aSBarry Smith #undef __FUNCT__ 12534a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 12546849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1255e24b481bSBarry Smith { 1256e24b481bSBarry Smith PetscFunctionBegin; 1257e24b481bSBarry Smith PetscFunctionReturn(0); 1258e24b481bSBarry Smith } 12597adad957SLisandro Dalcin #endif 1260e24b481bSBarry Smith 12619b94acceSBarry Smith /* -----------------------------------------------------------*/ 12624a2ae208SSatish Balay #undef __FUNCT__ 12634a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 126452baeb72SSatish Balay /*@ 12659b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 12669b94acceSBarry Smith 1267c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1268c7afd0dbSLois Curfman McInnes 1269c7afd0dbSLois Curfman McInnes Input Parameters: 1270906ed7ccSBarry Smith . comm - MPI communicator 12719b94acceSBarry Smith 12729b94acceSBarry Smith Output Parameter: 12739b94acceSBarry Smith . outsnes - the new SNES context 12749b94acceSBarry Smith 1275c7afd0dbSLois Curfman McInnes Options Database Keys: 1276c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1277c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1278c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1279c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1280c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1281c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1282c1f60f51SBarry Smith 128336851e7fSLois Curfman McInnes Level: beginner 128436851e7fSLois Curfman McInnes 12859b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 12869b94acceSBarry Smith 1287a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1288a8054027SBarry Smith 12899b94acceSBarry Smith @*/ 12907087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 12919b94acceSBarry Smith { 1292dfbe8321SBarry Smith PetscErrorCode ierr; 12939b94acceSBarry Smith SNES snes; 1294fa9f3622SBarry Smith SNESKSPEW *kctx; 129537fcc0dbSBarry Smith 12963a40ed3dSBarry Smith PetscFunctionBegin; 1297ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 12988ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 12998ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 13008ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 13018ba1e511SMatthew Knepley #endif 13028ba1e511SMatthew Knepley 13033194b578SJed Brown ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 13047adad957SLisandro Dalcin 130585385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 13062c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 130788976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 13089b94acceSBarry Smith snes->max_its = 50; 13099750a799SBarry Smith snes->max_funcs = 10000; 13109b94acceSBarry Smith snes->norm = 0.0; 1311b4874afaSBarry Smith snes->rtol = 1.e-8; 1312b4874afaSBarry Smith snes->ttol = 0.0; 131370441072SBarry Smith snes->abstol = 1.e-50; 1314c60f73f4SPeter Brune snes->stol = 1.e-8; 13154b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 13169b94acceSBarry Smith snes->nfuncs = 0; 131750ffb88aSMatthew Knepley snes->numFailures = 0; 131850ffb88aSMatthew Knepley snes->maxFailures = 1; 13197a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1320e35cf81dSBarry Smith snes->lagjacobian = 1; 1321a8054027SBarry Smith snes->lagpreconditioner = 1; 1322639f9d9dSBarry Smith snes->numbermonitors = 0; 13239b94acceSBarry Smith snes->data = 0; 13244dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1325186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 13266f24a144SLois Curfman McInnes snes->nwork = 0; 132758c9b817SLisandro Dalcin snes->work = 0; 132858c9b817SLisandro Dalcin snes->nvwork = 0; 132958c9b817SLisandro Dalcin snes->vwork = 0; 1330758f92a0SBarry Smith snes->conv_hist_len = 0; 1331758f92a0SBarry Smith snes->conv_hist_max = 0; 1332758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1333758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1334758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1335184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 133689b92e6fSPeter Brune snes->gssweeps = 1; 13379b94acceSBarry Smith 13383d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 13393d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 13403d4c4710SBarry Smith 13419b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 134238f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 13439b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 13449b94acceSBarry Smith kctx->version = 2; 13459b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 13469b94acceSBarry Smith this was too large for some test cases */ 134775567043SBarry Smith kctx->rtol_last = 0.0; 13489b94acceSBarry Smith kctx->rtol_max = .9; 13499b94acceSBarry Smith kctx->gamma = 1.0; 135062d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 135171f87433Sdalcinl kctx->alpha2 = kctx->alpha; 13529b94acceSBarry Smith kctx->threshold = .1; 135375567043SBarry Smith kctx->lresid_last = 0.0; 135475567043SBarry Smith kctx->norm_last = 0.0; 13559b94acceSBarry Smith 13569b94acceSBarry Smith *outsnes = snes; 13573a40ed3dSBarry Smith PetscFunctionReturn(0); 13589b94acceSBarry Smith } 13599b94acceSBarry Smith 13604a2ae208SSatish Balay #undef __FUNCT__ 13614a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 13629b94acceSBarry Smith /*@C 13639b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 13649b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 13659b94acceSBarry Smith equations. 13669b94acceSBarry Smith 13673f9fe445SBarry Smith Logically Collective on SNES 1368fee21e36SBarry Smith 1369c7afd0dbSLois Curfman McInnes Input Parameters: 1370c7afd0dbSLois Curfman McInnes + snes - the SNES context 1371c7afd0dbSLois Curfman McInnes . r - vector to store function value 1372de044059SHong Zhang . func - function evaluation routine 1373c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1374c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 13759b94acceSBarry Smith 1376c7afd0dbSLois Curfman McInnes Calling sequence of func: 13778d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1378c7afd0dbSLois Curfman McInnes 1379c586c404SJed Brown + snes - the SNES context 1380c586c404SJed Brown . x - state at which to evaluate residual 1381c586c404SJed Brown . f - vector to put residual 1382c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 13839b94acceSBarry Smith 13849b94acceSBarry Smith Notes: 13859b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 13869b94acceSBarry Smith $ f'(x) x = -f(x), 1387c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 13889b94acceSBarry Smith 138936851e7fSLois Curfman McInnes Level: beginner 139036851e7fSLois Curfman McInnes 13919b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 13929b94acceSBarry Smith 13938b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard() 13949b94acceSBarry Smith @*/ 13957087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 13969b94acceSBarry Smith { 139785385478SLisandro Dalcin PetscErrorCode ierr; 13986cab3a1bSJed Brown DM dm; 13996cab3a1bSJed Brown 14003a40ed3dSBarry Smith PetscFunctionBegin; 14010700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1402d2a683ecSLisandro Dalcin if (r) { 1403d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1404d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 140585385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 14066bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 140785385478SLisandro Dalcin snes->vec_func = r; 1408d2a683ecSLisandro Dalcin } 14096cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 14106cab3a1bSJed Brown ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr); 14113a40ed3dSBarry Smith PetscFunctionReturn(0); 14129b94acceSBarry Smith } 14139b94acceSBarry Smith 1414646217ecSPeter Brune 1415646217ecSPeter Brune #undef __FUNCT__ 1416646217ecSPeter Brune #define __FUNCT__ "SNESSetGS" 1417c79ef259SPeter Brune /*@C 1418c79ef259SPeter Brune SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for 1419c79ef259SPeter Brune use with composed nonlinear solvers. 1420c79ef259SPeter Brune 1421c79ef259SPeter Brune Input Parameters: 1422c79ef259SPeter Brune + snes - the SNES context 1423c79ef259SPeter Brune . gsfunc - function evaluation routine 1424c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 1425c79ef259SPeter Brune smoother evaluation routine (may be PETSC_NULL) 1426c79ef259SPeter Brune 1427c79ef259SPeter Brune Calling sequence of func: 1428c79ef259SPeter Brune $ func (SNES snes,Vec x,Vec b,void *ctx); 1429c79ef259SPeter Brune 1430c79ef259SPeter Brune + X - solution vector 1431c79ef259SPeter Brune . B - RHS vector 1432d28543b3SPeter Brune - ctx - optional user-defined Gauss-Seidel context 1433c79ef259SPeter Brune 1434c79ef259SPeter Brune Notes: 1435c79ef259SPeter Brune The GS routines are used by the composed nonlinear solver to generate 1436c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1437c79ef259SPeter Brune 1438d28543b3SPeter Brune Level: intermediate 1439c79ef259SPeter Brune 1440d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1441c79ef259SPeter Brune 1442c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS() 1443c79ef259SPeter Brune @*/ 14446cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx) 14456cab3a1bSJed Brown { 14466cab3a1bSJed Brown PetscErrorCode ierr; 14476cab3a1bSJed Brown DM dm; 14486cab3a1bSJed Brown 1449646217ecSPeter Brune PetscFunctionBegin; 14506cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14516cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 14526cab3a1bSJed Brown ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr); 1453646217ecSPeter Brune PetscFunctionReturn(0); 1454646217ecSPeter Brune } 1455646217ecSPeter Brune 1456d25893d9SBarry Smith #undef __FUNCT__ 145789b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps" 145889b92e6fSPeter Brune /*@ 145989b92e6fSPeter Brune SNESSetGSSweeps - Sets the number of sweeps of GS to use. 146089b92e6fSPeter Brune 146189b92e6fSPeter Brune Input Parameters: 146289b92e6fSPeter Brune + snes - the SNES context 146389b92e6fSPeter Brune - sweeps - the number of sweeps of GS to perform. 146489b92e6fSPeter Brune 146589b92e6fSPeter Brune Level: intermediate 146689b92e6fSPeter Brune 146789b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 146889b92e6fSPeter Brune 146989b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps() 147089b92e6fSPeter Brune @*/ 147189b92e6fSPeter Brune 147289b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) { 147389b92e6fSPeter Brune PetscFunctionBegin; 147489b92e6fSPeter Brune snes->gssweeps = sweeps; 147589b92e6fSPeter Brune PetscFunctionReturn(0); 147689b92e6fSPeter Brune } 147789b92e6fSPeter Brune 147889b92e6fSPeter Brune 147989b92e6fSPeter Brune #undef __FUNCT__ 148089b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps" 148189b92e6fSPeter Brune /*@ 148289b92e6fSPeter Brune SNESGetGSSweeps - Gets the number of sweeps GS will use. 148389b92e6fSPeter Brune 148489b92e6fSPeter Brune Input Parameters: 148589b92e6fSPeter Brune . snes - the SNES context 148689b92e6fSPeter Brune 148789b92e6fSPeter Brune Output Parameters: 148889b92e6fSPeter Brune . sweeps - the number of sweeps of GS to perform. 148989b92e6fSPeter Brune 149089b92e6fSPeter Brune Level: intermediate 149189b92e6fSPeter Brune 149289b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 149389b92e6fSPeter Brune 149489b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps() 149589b92e6fSPeter Brune @*/ 149689b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) { 149789b92e6fSPeter Brune PetscFunctionBegin; 149889b92e6fSPeter Brune *sweeps = snes->gssweeps; 149989b92e6fSPeter Brune PetscFunctionReturn(0); 150089b92e6fSPeter Brune } 150189b92e6fSPeter Brune 150289b92e6fSPeter Brune #undef __FUNCT__ 15038b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 15048b0a5094SBarry Smith PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 15058b0a5094SBarry Smith { 15068b0a5094SBarry Smith PetscErrorCode ierr; 15076cab3a1bSJed Brown void *functx,*jacctx; 15086cab3a1bSJed Brown 15098b0a5094SBarry Smith PetscFunctionBegin; 15106cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 15116cab3a1bSJed Brown ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr); 15128b0a5094SBarry Smith /* A(x)*x - b(x) */ 15136cab3a1bSJed Brown ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr); 15146cab3a1bSJed Brown ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr); 15158b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 15168b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 15178b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 15188b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 15198b0a5094SBarry Smith PetscFunctionReturn(0); 15208b0a5094SBarry Smith } 15218b0a5094SBarry Smith 15228b0a5094SBarry Smith #undef __FUNCT__ 15238b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 15248b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 15258b0a5094SBarry Smith { 15268b0a5094SBarry Smith PetscFunctionBegin; 15278b0a5094SBarry Smith *flag = snes->matstruct; 15288b0a5094SBarry Smith PetscFunctionReturn(0); 15298b0a5094SBarry Smith } 15308b0a5094SBarry Smith 15318b0a5094SBarry Smith #undef __FUNCT__ 15328b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 15338b0a5094SBarry Smith /*@C 15340d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 15358b0a5094SBarry Smith 15368b0a5094SBarry Smith Logically Collective on SNES 15378b0a5094SBarry Smith 15388b0a5094SBarry Smith Input Parameters: 15398b0a5094SBarry Smith + snes - the SNES context 15408b0a5094SBarry Smith . r - vector to store function value 15418b0a5094SBarry Smith . func - function evaluation routine 15428b0a5094SBarry 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) 15438b0a5094SBarry Smith . mat - matrix to store A 15448b0a5094SBarry Smith . mfunc - function to compute matrix value 15458b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 15468b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 15478b0a5094SBarry Smith 15488b0a5094SBarry Smith Calling sequence of func: 15498b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 15508b0a5094SBarry Smith 15518b0a5094SBarry Smith + f - function vector 15528b0a5094SBarry Smith - ctx - optional user-defined function context 15538b0a5094SBarry Smith 15548b0a5094SBarry Smith Calling sequence of mfunc: 15558b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 15568b0a5094SBarry Smith 15578b0a5094SBarry Smith + x - input vector 15588b0a5094SBarry 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(), 15598b0a5094SBarry Smith normally just pass mat in this location 15608b0a5094SBarry Smith . mat - form A(x) matrix 15618b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 15628b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 15638b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 15648b0a5094SBarry Smith 15658b0a5094SBarry Smith Notes: 15668b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 15678b0a5094SBarry Smith 15688b0a5094SBarry 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} 15698b0a5094SBarry 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. 15708b0a5094SBarry Smith 15718b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 15728b0a5094SBarry Smith 15730d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 15740d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 15758b0a5094SBarry Smith 15768b0a5094SBarry 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 15778b0a5094SBarry 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 15788b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 15798b0a5094SBarry Smith 15808b0a5094SBarry Smith Level: beginner 15818b0a5094SBarry Smith 15828b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 15838b0a5094SBarry Smith 15840d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard() 15858b0a5094SBarry Smith @*/ 15868b0a5094SBarry 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) 15878b0a5094SBarry Smith { 15888b0a5094SBarry Smith PetscErrorCode ierr; 15898b0a5094SBarry Smith PetscFunctionBegin; 15908b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15918b0a5094SBarry Smith snes->ops->computepfunction = func; 15928b0a5094SBarry Smith snes->ops->computepjacobian = mfunc; 15938b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 15948b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 15958b0a5094SBarry Smith PetscFunctionReturn(0); 15968b0a5094SBarry Smith } 15978b0a5094SBarry Smith 15988b0a5094SBarry Smith #undef __FUNCT__ 1599d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1600d25893d9SBarry Smith /*@C 1601d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1602d25893d9SBarry Smith 1603d25893d9SBarry Smith Logically Collective on SNES 1604d25893d9SBarry Smith 1605d25893d9SBarry Smith Input Parameters: 1606d25893d9SBarry Smith + snes - the SNES context 1607d25893d9SBarry Smith . func - function evaluation routine 1608d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1609d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1610d25893d9SBarry Smith 1611d25893d9SBarry Smith Calling sequence of func: 1612d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1613d25893d9SBarry Smith 1614d25893d9SBarry Smith . f - function vector 1615d25893d9SBarry Smith - ctx - optional user-defined function context 1616d25893d9SBarry Smith 1617d25893d9SBarry Smith Level: intermediate 1618d25893d9SBarry Smith 1619d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1620d25893d9SBarry Smith 1621d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1622d25893d9SBarry Smith @*/ 1623d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1624d25893d9SBarry Smith { 1625d25893d9SBarry Smith PetscFunctionBegin; 1626d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1627d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1628d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1629d25893d9SBarry Smith PetscFunctionReturn(0); 1630d25893d9SBarry Smith } 1631d25893d9SBarry Smith 16323ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 16333ab0aad5SBarry Smith #undef __FUNCT__ 16341096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 16351096aae1SMatthew Knepley /*@C 16361096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 16371096aae1SMatthew Knepley it assumes a zero right hand side. 16381096aae1SMatthew Knepley 16393f9fe445SBarry Smith Logically Collective on SNES 16401096aae1SMatthew Knepley 16411096aae1SMatthew Knepley Input Parameter: 16421096aae1SMatthew Knepley . snes - the SNES context 16431096aae1SMatthew Knepley 16441096aae1SMatthew Knepley Output Parameter: 1645bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 16461096aae1SMatthew Knepley 16471096aae1SMatthew Knepley Level: intermediate 16481096aae1SMatthew Knepley 16491096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 16501096aae1SMatthew Knepley 165185385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 16521096aae1SMatthew Knepley @*/ 16537087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 16541096aae1SMatthew Knepley { 16551096aae1SMatthew Knepley PetscFunctionBegin; 16560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16571096aae1SMatthew Knepley PetscValidPointer(rhs,2); 165885385478SLisandro Dalcin *rhs = snes->vec_rhs; 16591096aae1SMatthew Knepley PetscFunctionReturn(0); 16601096aae1SMatthew Knepley } 16611096aae1SMatthew Knepley 16621096aae1SMatthew Knepley #undef __FUNCT__ 16634a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 16649b94acceSBarry Smith /*@ 166536851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 16669b94acceSBarry Smith SNESSetFunction(). 16679b94acceSBarry Smith 1668c7afd0dbSLois Curfman McInnes Collective on SNES 1669c7afd0dbSLois Curfman McInnes 16709b94acceSBarry Smith Input Parameters: 1671c7afd0dbSLois Curfman McInnes + snes - the SNES context 1672c7afd0dbSLois Curfman McInnes - x - input vector 16739b94acceSBarry Smith 16749b94acceSBarry Smith Output Parameter: 16753638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 16769b94acceSBarry Smith 16771bffabb2SLois Curfman McInnes Notes: 167836851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 167936851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 168036851e7fSLois Curfman McInnes themselves. 168136851e7fSLois Curfman McInnes 168236851e7fSLois Curfman McInnes Level: developer 168336851e7fSLois Curfman McInnes 16849b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 16859b94acceSBarry Smith 1686a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 16879b94acceSBarry Smith @*/ 16887087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 16899b94acceSBarry Smith { 1690dfbe8321SBarry Smith PetscErrorCode ierr; 16916cab3a1bSJed Brown DM dm; 16926cab3a1bSJed Brown SNESDM sdm; 16939b94acceSBarry Smith 16943a40ed3dSBarry Smith PetscFunctionBegin; 16950700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16960700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 16970700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1698c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1699c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 17004ec14c9cSBarry Smith VecValidValues(x,2,PETSC_TRUE); 1701184914b5SBarry Smith 17026cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 17036cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 1704d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 17056cab3a1bSJed Brown if (sdm->computefunction) { 1706d64ed03dSBarry Smith PetscStackPush("SNES user function"); 17076cab3a1bSJed Brown ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 1708d64ed03dSBarry Smith PetscStackPop; 170973250ac0SBarry Smith } else if (snes->dm) { 1710644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1711c90fad12SPeter Brune } else if (snes->vec_rhs) { 1712c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1713644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 171485385478SLisandro Dalcin if (snes->vec_rhs) { 171585385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 17163ab0aad5SBarry Smith } 1717ae3c334cSLois Curfman McInnes snes->nfuncs++; 1718d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 17194ec14c9cSBarry Smith VecValidValues(y,3,PETSC_FALSE); 17203a40ed3dSBarry Smith PetscFunctionReturn(0); 17219b94acceSBarry Smith } 17229b94acceSBarry Smith 17234a2ae208SSatish Balay #undef __FUNCT__ 1724646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1725c79ef259SPeter Brune /*@ 1726c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1727c79ef259SPeter Brune SNESSetGS(). 1728c79ef259SPeter Brune 1729c79ef259SPeter Brune Collective on SNES 1730c79ef259SPeter Brune 1731c79ef259SPeter Brune Input Parameters: 1732c79ef259SPeter Brune + snes - the SNES context 1733c79ef259SPeter Brune . x - input vector 1734c79ef259SPeter Brune - b - rhs vector 1735c79ef259SPeter Brune 1736c79ef259SPeter Brune Output Parameter: 1737c79ef259SPeter Brune . x - new solution vector 1738c79ef259SPeter Brune 1739c79ef259SPeter Brune Notes: 1740c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1741c79ef259SPeter Brune implementations, so most users would not generally call this routine 1742c79ef259SPeter Brune themselves. 1743c79ef259SPeter Brune 1744c79ef259SPeter Brune Level: developer 1745c79ef259SPeter Brune 1746c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1747c79ef259SPeter Brune 1748c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1749c79ef259SPeter Brune @*/ 1750646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1751646217ecSPeter Brune { 1752646217ecSPeter Brune PetscErrorCode ierr; 175389b92e6fSPeter Brune PetscInt i; 17546cab3a1bSJed Brown DM dm; 17556cab3a1bSJed Brown SNESDM sdm; 1756646217ecSPeter Brune 1757646217ecSPeter Brune PetscFunctionBegin; 1758646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1759646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1760646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1761646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 1762646217ecSPeter Brune if(b) PetscCheckSameComm(snes,1,b,3); 17634ec14c9cSBarry Smith if (b) VecValidValues(b,2,PETSC_TRUE); 1764701cf23dSPeter Brune ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 17656cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 17666cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 17676cab3a1bSJed Brown if (sdm->computegs) { 176889b92e6fSPeter Brune for (i = 0; i < snes->gssweeps; i++) { 1769646217ecSPeter Brune PetscStackPush("SNES user GS"); 17706cab3a1bSJed Brown ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 1771646217ecSPeter Brune PetscStackPop; 177289b92e6fSPeter Brune } 1773646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 1774701cf23dSPeter Brune ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 17754ec14c9cSBarry Smith VecValidValues(x,3,PETSC_FALSE); 1776646217ecSPeter Brune PetscFunctionReturn(0); 1777646217ecSPeter Brune } 1778646217ecSPeter Brune 1779646217ecSPeter Brune 1780646217ecSPeter Brune #undef __FUNCT__ 17814a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 178262fef451SLois Curfman McInnes /*@ 178362fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 178462fef451SLois Curfman McInnes set with SNESSetJacobian(). 178562fef451SLois Curfman McInnes 1786c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1787c7afd0dbSLois Curfman McInnes 178862fef451SLois Curfman McInnes Input Parameters: 1789c7afd0dbSLois Curfman McInnes + snes - the SNES context 1790c7afd0dbSLois Curfman McInnes - x - input vector 179162fef451SLois Curfman McInnes 179262fef451SLois Curfman McInnes Output Parameters: 1793c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 179462fef451SLois Curfman McInnes . B - optional preconditioning matrix 17952b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1796fee21e36SBarry Smith 1797e35cf81dSBarry Smith Options Database Keys: 1798e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1799693365a8SJed Brown . -snes_lag_jacobian <lag> 1800693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1801693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1802693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 18034c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1804c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 1805c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 1806c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 1807c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 1808c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 18094c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 1810c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 1811c01495d3SJed Brown 1812e35cf81dSBarry Smith 181362fef451SLois Curfman McInnes Notes: 181462fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 181562fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 181662fef451SLois Curfman McInnes 181794b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1818dc5a77f8SLois Curfman McInnes flag parameter. 181962fef451SLois Curfman McInnes 182036851e7fSLois Curfman McInnes Level: developer 182136851e7fSLois Curfman McInnes 182262fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 182362fef451SLois Curfman McInnes 1824e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 182562fef451SLois Curfman McInnes @*/ 18267087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 18279b94acceSBarry Smith { 1828dfbe8321SBarry Smith PetscErrorCode ierr; 1829ace3abfcSBarry Smith PetscBool flag; 18306cab3a1bSJed Brown DM dm; 18316cab3a1bSJed Brown SNESDM sdm; 18323a40ed3dSBarry Smith 18333a40ed3dSBarry Smith PetscFunctionBegin; 18340700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 18350700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 18364482741eSBarry Smith PetscValidPointer(flg,5); 1837c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 18384ec14c9cSBarry Smith VecValidValues(X,2,PETSC_TRUE); 18396cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18406cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 18416cab3a1bSJed Brown if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 1842ebd3b9afSBarry Smith 1843ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1844ebd3b9afSBarry Smith 1845fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 1846fe3ffe1eSBarry Smith snes->lagjacobian = -1; 1847fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1848fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 1849e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1850e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1851ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1852ebd3b9afSBarry Smith if (flag) { 1853ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1854ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1855ebd3b9afSBarry Smith } 1856e35cf81dSBarry Smith PetscFunctionReturn(0); 1857e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1858e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1859e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1860ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1861ebd3b9afSBarry Smith if (flag) { 1862ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1863ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1864ebd3b9afSBarry Smith } 1865e35cf81dSBarry Smith PetscFunctionReturn(0); 1866e35cf81dSBarry Smith } 1867e35cf81dSBarry Smith 1868c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 1869e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1870d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 18716cab3a1bSJed Brown ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr); 1872d64ed03dSBarry Smith PetscStackPop; 1873d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1874a8054027SBarry Smith 18753b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 18763b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 18773b4f5425SBarry Smith snes->lagpreconditioner = -1; 18783b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 1879a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1880a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 1881a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 1882a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1883a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 1884a8054027SBarry Smith } 1885a8054027SBarry Smith 18866d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 18870700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 18880700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 1889693365a8SJed Brown { 1890693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 1891693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 1892693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 1893693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 1894693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 1895693365a8SJed Brown if (flag || flag_draw || flag_contour) { 1896693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 1897693365a8SJed Brown MatStructure mstruct; 1898693365a8SJed Brown PetscViewer vdraw,vstdout; 18996b3a5b13SJed Brown PetscBool flg; 1900693365a8SJed Brown if (flag_operator) { 1901693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 1902693365a8SJed Brown Bexp = Bexp_mine; 1903693365a8SJed Brown } else { 1904693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 1905693365a8SJed Brown ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 1906693365a8SJed Brown if (flg) Bexp = *B; 1907693365a8SJed Brown else { 1908693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 1909693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 1910693365a8SJed Brown Bexp = Bexp_mine; 1911693365a8SJed Brown } 1912693365a8SJed Brown } 1913693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 1914693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 1915693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 1916693365a8SJed Brown if (flag_draw || flag_contour) { 1917693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 1918693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 1919693365a8SJed Brown } else vdraw = PETSC_NULL; 1920693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 1921693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 1922693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 1923693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 1924693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1925693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 1926693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1927693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 1928693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1929693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 1930693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 1931693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 1932693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 1933693365a8SJed Brown } 1934693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 1935693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 1936693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 1937693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 1938693365a8SJed Brown } 1939693365a8SJed Brown } 19404c30e9fbSJed Brown { 19416719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 19426719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 19434c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 19446719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 19454c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 19464c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 19476719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 19486719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 19496719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 19506719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 19514c30e9fbSJed Brown Mat Bfd; 19524c30e9fbSJed Brown MatStructure mstruct; 19534c30e9fbSJed Brown PetscViewer vdraw,vstdout; 19544c30e9fbSJed Brown ISColoring iscoloring; 19554c30e9fbSJed Brown MatFDColoring matfdcoloring; 19564c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 19574c30e9fbSJed Brown void *funcctx; 19586719d8e4SJed Brown PetscReal norm1,norm2,normmax; 19594c30e9fbSJed Brown 19604c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 19614c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 19624c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 19634c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 19644c30e9fbSJed Brown 19654c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 19664c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 19674c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 19684c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 19694c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 19704c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 19714c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 19724c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 19734c30e9fbSJed Brown 19744c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 19754c30e9fbSJed Brown if (flag_draw || flag_contour) { 19764c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 19774c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 19784c30e9fbSJed Brown } else vdraw = PETSC_NULL; 19794c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 19806719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 19814c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 19824c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 19836719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 19844c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 19854c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 19864c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 19876719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 19884c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 19896719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 19906719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 19914c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 19924c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 19934c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 19944c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 19954c30e9fbSJed Brown } 19964c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 19976719d8e4SJed Brown 19986719d8e4SJed Brown if (flag_threshold) { 19996719d8e4SJed Brown PetscInt bs,rstart,rend,i; 20006719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 20016719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 20026719d8e4SJed Brown for (i=rstart; i<rend; i++) { 20036719d8e4SJed Brown const PetscScalar *ba,*ca; 20046719d8e4SJed Brown const PetscInt *bj,*cj; 20056719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 20066719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 20076719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 20086719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 20096719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 20106719d8e4SJed Brown for (j=0; j<bn; j++) { 20116719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 20126719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 20136719d8e4SJed Brown maxentrycol = bj[j]; 20146719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 20156719d8e4SJed Brown } 20166719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 20176719d8e4SJed Brown maxdiffcol = bj[j]; 20186719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 20196719d8e4SJed Brown } 20206719d8e4SJed Brown if (rdiff > maxrdiff) { 20216719d8e4SJed Brown maxrdiffcol = bj[j]; 20226719d8e4SJed Brown maxrdiff = rdiff; 20236719d8e4SJed Brown } 20246719d8e4SJed Brown } 20256719d8e4SJed Brown if (maxrdiff > 1) { 20266719d8e4SJed 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); 20276719d8e4SJed Brown for (j=0; j<bn; j++) { 20286719d8e4SJed Brown PetscReal rdiff; 20296719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 20306719d8e4SJed Brown if (rdiff > 1) { 20316719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 20326719d8e4SJed Brown } 20336719d8e4SJed Brown } 20346719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 20356719d8e4SJed Brown } 20366719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 20376719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 20386719d8e4SJed Brown } 20396719d8e4SJed Brown } 20404c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 20414c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 20424c30e9fbSJed Brown } 20434c30e9fbSJed Brown } 20443a40ed3dSBarry Smith PetscFunctionReturn(0); 20459b94acceSBarry Smith } 20469b94acceSBarry Smith 20474a2ae208SSatish Balay #undef __FUNCT__ 20484a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 20499b94acceSBarry Smith /*@C 20509b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2051044dda88SLois Curfman McInnes location to store the matrix. 20529b94acceSBarry Smith 20533f9fe445SBarry Smith Logically Collective on SNES and Mat 2054c7afd0dbSLois Curfman McInnes 20559b94acceSBarry Smith Input Parameters: 2056c7afd0dbSLois Curfman McInnes + snes - the SNES context 20579b94acceSBarry Smith . A - Jacobian matrix 20589b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 2059efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 2060c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 2061efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 20629b94acceSBarry Smith 20639b94acceSBarry Smith Calling sequence of func: 20648d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 20659b94acceSBarry Smith 2066c7afd0dbSLois Curfman McInnes + x - input vector 20679b94acceSBarry Smith . A - Jacobian matrix 20689b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 2069ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 20702b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 2071c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 20729b94acceSBarry Smith 20739b94acceSBarry Smith Notes: 207494b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 20752cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 2076ac21db08SLois Curfman McInnes 2077ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 20789b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 20799b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 20809b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 20819b94acceSBarry Smith throughout the global iterations. 20829b94acceSBarry Smith 208316913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 208416913363SBarry Smith each matrix. 208516913363SBarry Smith 2086a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 2087a8a26c1eSJed Brown must be a MatFDColoring. 2088a8a26c1eSJed Brown 2089c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2090c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2091c3cc8fd1SJed Brown 209236851e7fSLois Curfman McInnes Level: beginner 209336851e7fSLois Curfman McInnes 20949b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 20959b94acceSBarry Smith 20963ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 20979b94acceSBarry Smith @*/ 20987087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 20999b94acceSBarry Smith { 2100dfbe8321SBarry Smith PetscErrorCode ierr; 21016cab3a1bSJed Brown DM dm; 21023a7fca6bSBarry Smith 21033a40ed3dSBarry Smith PetscFunctionBegin; 21040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 21050700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 21060700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 2107c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 210806975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 21096cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 21106cab3a1bSJed Brown ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr); 21113a7fca6bSBarry Smith if (A) { 21127dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 21136bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 21149b94acceSBarry Smith snes->jacobian = A; 21153a7fca6bSBarry Smith } 21163a7fca6bSBarry Smith if (B) { 21177dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 21186bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 21199b94acceSBarry Smith snes->jacobian_pre = B; 21203a7fca6bSBarry Smith } 21213a40ed3dSBarry Smith PetscFunctionReturn(0); 21229b94acceSBarry Smith } 212362fef451SLois Curfman McInnes 21244a2ae208SSatish Balay #undef __FUNCT__ 21254a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 2126c2aafc4cSSatish Balay /*@C 2127b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2128b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2129b4fd4287SBarry Smith 2130c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2131c7afd0dbSLois Curfman McInnes 2132b4fd4287SBarry Smith Input Parameter: 2133b4fd4287SBarry Smith . snes - the nonlinear solver context 2134b4fd4287SBarry Smith 2135b4fd4287SBarry Smith Output Parameters: 2136c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 2137b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 213870e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 213970e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 2140fee21e36SBarry Smith 214136851e7fSLois Curfman McInnes Level: advanced 214236851e7fSLois Curfman McInnes 2143b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 2144b4fd4287SBarry Smith @*/ 21457087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 2146b4fd4287SBarry Smith { 21476cab3a1bSJed Brown PetscErrorCode ierr; 21486cab3a1bSJed Brown DM dm; 21496cab3a1bSJed Brown SNESDM sdm; 21506cab3a1bSJed Brown 21513a40ed3dSBarry Smith PetscFunctionBegin; 21520700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2153b4fd4287SBarry Smith if (A) *A = snes->jacobian; 2154b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 21556cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 21566cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 21576cab3a1bSJed Brown if (func) *func = sdm->computejacobian; 21586cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 21593a40ed3dSBarry Smith PetscFunctionReturn(0); 2160b4fd4287SBarry Smith } 2161b4fd4287SBarry Smith 21629b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 21639b94acceSBarry Smith 21644a2ae208SSatish Balay #undef __FUNCT__ 21654a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 21669b94acceSBarry Smith /*@ 21679b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2168272ac6f2SLois Curfman McInnes of a nonlinear solver. 21699b94acceSBarry Smith 2170fee21e36SBarry Smith Collective on SNES 2171fee21e36SBarry Smith 2172c7afd0dbSLois Curfman McInnes Input Parameters: 217370e92668SMatthew Knepley . snes - the SNES context 2174c7afd0dbSLois Curfman McInnes 2175272ac6f2SLois Curfman McInnes Notes: 2176272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2177272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2178272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2179272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2180272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2181272ac6f2SLois Curfman McInnes 218236851e7fSLois Curfman McInnes Level: advanced 218336851e7fSLois Curfman McInnes 21849b94acceSBarry Smith .keywords: SNES, nonlinear, setup 21859b94acceSBarry Smith 21869b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 21879b94acceSBarry Smith @*/ 21887087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 21899b94acceSBarry Smith { 2190dfbe8321SBarry Smith PetscErrorCode ierr; 21916cab3a1bSJed Brown DM dm; 21926cab3a1bSJed Brown SNESDM sdm; 21933a40ed3dSBarry Smith 21943a40ed3dSBarry Smith PetscFunctionBegin; 21950700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 21964dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 21979b94acceSBarry Smith 21987adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 219985385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 220085385478SLisandro Dalcin } 220185385478SLisandro Dalcin 2202a63bb30eSJed Brown ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 220317186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 220458c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 220558c9b817SLisandro Dalcin 220658c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 220758c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 220858c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 220958c9b817SLisandro Dalcin } 221058c9b817SLisandro Dalcin 22116cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 22126cab3a1bSJed Brown ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */ 22136cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 22146cab3a1bSJed Brown if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc"); 22156cab3a1bSJed Brown if (!snes->vec_func) { 22166cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2217214df951SJed Brown } 2218efd51863SBarry Smith 2219b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 2220b710008aSBarry Smith 2221f1c6b773SPeter Brune if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);} 22229e764e56SPeter Brune 2223d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 2224d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2225d25893d9SBarry Smith } 2226d25893d9SBarry Smith 2227410397dcSLisandro Dalcin if (snes->ops->setup) { 2228410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2229410397dcSLisandro Dalcin } 223058c9b817SLisandro Dalcin 22317aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 22323a40ed3dSBarry Smith PetscFunctionReturn(0); 22339b94acceSBarry Smith } 22349b94acceSBarry Smith 22354a2ae208SSatish Balay #undef __FUNCT__ 223637596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 223737596af1SLisandro Dalcin /*@ 223837596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 223937596af1SLisandro Dalcin 224037596af1SLisandro Dalcin Collective on SNES 224137596af1SLisandro Dalcin 224237596af1SLisandro Dalcin Input Parameter: 224337596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 224437596af1SLisandro Dalcin 2245d25893d9SBarry Smith Level: intermediate 2246d25893d9SBarry Smith 2247d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 224837596af1SLisandro Dalcin 224937596af1SLisandro Dalcin .keywords: SNES, destroy 225037596af1SLisandro Dalcin 225137596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 225237596af1SLisandro Dalcin @*/ 225337596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 225437596af1SLisandro Dalcin { 225537596af1SLisandro Dalcin PetscErrorCode ierr; 225637596af1SLisandro Dalcin 225737596af1SLisandro Dalcin PetscFunctionBegin; 225837596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2259d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2260d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2261d25893d9SBarry Smith snes->user = PETSC_NULL; 2262d25893d9SBarry Smith } 22638a23116dSBarry Smith if (snes->pc) { 22648a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 22658a23116dSBarry Smith } 22668a23116dSBarry Smith 226737596af1SLisandro Dalcin if (snes->ops->reset) { 226837596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 226937596af1SLisandro Dalcin } 22709e764e56SPeter Brune if (snes->ksp) { 22719e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 22729e764e56SPeter Brune } 22739e764e56SPeter Brune 22749e764e56SPeter Brune if (snes->linesearch) { 2275f1c6b773SPeter Brune ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 22769e764e56SPeter Brune } 22779e764e56SPeter Brune 22786bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 22796bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 22806bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 22816bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 22826bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 22836bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2284c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2285c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 228637596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 228737596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 228837596af1SLisandro Dalcin PetscFunctionReturn(0); 228937596af1SLisandro Dalcin } 229037596af1SLisandro Dalcin 229137596af1SLisandro Dalcin #undef __FUNCT__ 22924a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 229352baeb72SSatish Balay /*@ 22949b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 22959b94acceSBarry Smith with SNESCreate(). 22969b94acceSBarry Smith 2297c7afd0dbSLois Curfman McInnes Collective on SNES 2298c7afd0dbSLois Curfman McInnes 22999b94acceSBarry Smith Input Parameter: 23009b94acceSBarry Smith . snes - the SNES context 23019b94acceSBarry Smith 230236851e7fSLois Curfman McInnes Level: beginner 230336851e7fSLois Curfman McInnes 23049b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 23059b94acceSBarry Smith 230663a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 23079b94acceSBarry Smith @*/ 23086bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 23099b94acceSBarry Smith { 23106849ba73SBarry Smith PetscErrorCode ierr; 23113a40ed3dSBarry Smith 23123a40ed3dSBarry Smith PetscFunctionBegin; 23136bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 23146bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 23156bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2316d4bb536fSBarry Smith 23176bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 23188a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 23196b8b9a38SLisandro Dalcin 2320be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 23216bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 23226bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 23236d4c513bSLisandro Dalcin 23246bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 23256bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 2326f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 23276b8b9a38SLisandro Dalcin 23286bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 23296bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 23306bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 23316b8b9a38SLisandro Dalcin } 23326bf464f9SBarry Smith if ((*snes)->conv_malloc) { 23336bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 23346bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 233558c9b817SLisandro Dalcin } 23366bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2337a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 23383a40ed3dSBarry Smith PetscFunctionReturn(0); 23399b94acceSBarry Smith } 23409b94acceSBarry Smith 23419b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 23429b94acceSBarry Smith 23434a2ae208SSatish Balay #undef __FUNCT__ 2344a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2345a8054027SBarry Smith /*@ 2346a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2347a8054027SBarry Smith 23483f9fe445SBarry Smith Logically Collective on SNES 2349a8054027SBarry Smith 2350a8054027SBarry Smith Input Parameters: 2351a8054027SBarry Smith + snes - the SNES context 2352a8054027SBarry 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 23533b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2354a8054027SBarry Smith 2355a8054027SBarry Smith Options Database Keys: 2356a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2357a8054027SBarry Smith 2358a8054027SBarry Smith Notes: 2359a8054027SBarry Smith The default is 1 2360a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2361a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2362a8054027SBarry Smith 2363a8054027SBarry Smith Level: intermediate 2364a8054027SBarry Smith 2365a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2366a8054027SBarry Smith 2367e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2368a8054027SBarry Smith 2369a8054027SBarry Smith @*/ 23707087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2371a8054027SBarry Smith { 2372a8054027SBarry Smith PetscFunctionBegin; 23730700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2374e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2375e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2376c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2377a8054027SBarry Smith snes->lagpreconditioner = lag; 2378a8054027SBarry Smith PetscFunctionReturn(0); 2379a8054027SBarry Smith } 2380a8054027SBarry Smith 2381a8054027SBarry Smith #undef __FUNCT__ 2382efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2383efd51863SBarry Smith /*@ 2384efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2385efd51863SBarry Smith 2386efd51863SBarry Smith Logically Collective on SNES 2387efd51863SBarry Smith 2388efd51863SBarry Smith Input Parameters: 2389efd51863SBarry Smith + snes - the SNES context 2390efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2391efd51863SBarry Smith 2392efd51863SBarry Smith Options Database Keys: 2393efd51863SBarry Smith . -snes_grid_sequence <steps> 2394efd51863SBarry Smith 2395efd51863SBarry Smith Level: intermediate 2396efd51863SBarry Smith 2397c0df2a02SJed Brown Notes: 2398c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2399c0df2a02SJed Brown 2400efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2401efd51863SBarry Smith 2402efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2403efd51863SBarry Smith 2404efd51863SBarry Smith @*/ 2405efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2406efd51863SBarry Smith { 2407efd51863SBarry Smith PetscFunctionBegin; 2408efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2409efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2410efd51863SBarry Smith snes->gridsequence = steps; 2411efd51863SBarry Smith PetscFunctionReturn(0); 2412efd51863SBarry Smith } 2413efd51863SBarry Smith 2414efd51863SBarry Smith #undef __FUNCT__ 2415a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2416a8054027SBarry Smith /*@ 2417a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2418a8054027SBarry Smith 24193f9fe445SBarry Smith Not Collective 2420a8054027SBarry Smith 2421a8054027SBarry Smith Input Parameter: 2422a8054027SBarry Smith . snes - the SNES context 2423a8054027SBarry Smith 2424a8054027SBarry Smith Output Parameter: 2425a8054027SBarry 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 24263b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2427a8054027SBarry Smith 2428a8054027SBarry Smith Options Database Keys: 2429a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2430a8054027SBarry Smith 2431a8054027SBarry Smith Notes: 2432a8054027SBarry Smith The default is 1 2433a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2434a8054027SBarry Smith 2435a8054027SBarry Smith Level: intermediate 2436a8054027SBarry Smith 2437a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2438a8054027SBarry Smith 2439a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2440a8054027SBarry Smith 2441a8054027SBarry Smith @*/ 24427087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2443a8054027SBarry Smith { 2444a8054027SBarry Smith PetscFunctionBegin; 24450700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2446a8054027SBarry Smith *lag = snes->lagpreconditioner; 2447a8054027SBarry Smith PetscFunctionReturn(0); 2448a8054027SBarry Smith } 2449a8054027SBarry Smith 2450a8054027SBarry Smith #undef __FUNCT__ 2451e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2452e35cf81dSBarry Smith /*@ 2453e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2454e35cf81dSBarry Smith often the preconditioner is rebuilt. 2455e35cf81dSBarry Smith 24563f9fe445SBarry Smith Logically Collective on SNES 2457e35cf81dSBarry Smith 2458e35cf81dSBarry Smith Input Parameters: 2459e35cf81dSBarry Smith + snes - the SNES context 2460e35cf81dSBarry 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 2461fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2462e35cf81dSBarry Smith 2463e35cf81dSBarry Smith Options Database Keys: 2464e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2465e35cf81dSBarry Smith 2466e35cf81dSBarry Smith Notes: 2467e35cf81dSBarry Smith The default is 1 2468e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2469fe3ffe1eSBarry 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 2470fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2471e35cf81dSBarry Smith 2472e35cf81dSBarry Smith Level: intermediate 2473e35cf81dSBarry Smith 2474e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2475e35cf81dSBarry Smith 2476e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2477e35cf81dSBarry Smith 2478e35cf81dSBarry Smith @*/ 24797087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2480e35cf81dSBarry Smith { 2481e35cf81dSBarry Smith PetscFunctionBegin; 24820700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2483e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2484e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2485c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2486e35cf81dSBarry Smith snes->lagjacobian = lag; 2487e35cf81dSBarry Smith PetscFunctionReturn(0); 2488e35cf81dSBarry Smith } 2489e35cf81dSBarry Smith 2490e35cf81dSBarry Smith #undef __FUNCT__ 2491e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2492e35cf81dSBarry Smith /*@ 2493e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2494e35cf81dSBarry Smith 24953f9fe445SBarry Smith Not Collective 2496e35cf81dSBarry Smith 2497e35cf81dSBarry Smith Input Parameter: 2498e35cf81dSBarry Smith . snes - the SNES context 2499e35cf81dSBarry Smith 2500e35cf81dSBarry Smith Output Parameter: 2501e35cf81dSBarry 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 2502e35cf81dSBarry Smith the Jacobian is built etc. 2503e35cf81dSBarry Smith 2504e35cf81dSBarry Smith Options Database Keys: 2505e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2506e35cf81dSBarry Smith 2507e35cf81dSBarry Smith Notes: 2508e35cf81dSBarry Smith The default is 1 2509e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2510e35cf81dSBarry Smith 2511e35cf81dSBarry Smith Level: intermediate 2512e35cf81dSBarry Smith 2513e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2514e35cf81dSBarry Smith 2515e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2516e35cf81dSBarry Smith 2517e35cf81dSBarry Smith @*/ 25187087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2519e35cf81dSBarry Smith { 2520e35cf81dSBarry Smith PetscFunctionBegin; 25210700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2522e35cf81dSBarry Smith *lag = snes->lagjacobian; 2523e35cf81dSBarry Smith PetscFunctionReturn(0); 2524e35cf81dSBarry Smith } 2525e35cf81dSBarry Smith 2526e35cf81dSBarry Smith #undef __FUNCT__ 25274a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 25289b94acceSBarry Smith /*@ 2529d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 25309b94acceSBarry Smith 25313f9fe445SBarry Smith Logically Collective on SNES 2532c7afd0dbSLois Curfman McInnes 25339b94acceSBarry Smith Input Parameters: 2534c7afd0dbSLois Curfman McInnes + snes - the SNES context 253570441072SBarry Smith . abstol - absolute convergence tolerance 253633174efeSLois Curfman McInnes . rtol - relative convergence tolerance 253733174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 253833174efeSLois Curfman McInnes of the change in the solution between steps 253933174efeSLois Curfman McInnes . maxit - maximum number of iterations 2540c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2541fee21e36SBarry Smith 254233174efeSLois Curfman McInnes Options Database Keys: 254370441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2544c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2545c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2546c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2547c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 25489b94acceSBarry Smith 2549d7a720efSLois Curfman McInnes Notes: 25509b94acceSBarry Smith The default maximum number of iterations is 50. 25519b94acceSBarry Smith The default maximum number of function evaluations is 1000. 25529b94acceSBarry Smith 255336851e7fSLois Curfman McInnes Level: intermediate 255436851e7fSLois Curfman McInnes 255533174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 25569b94acceSBarry Smith 25572492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 25589b94acceSBarry Smith @*/ 25597087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 25609b94acceSBarry Smith { 25613a40ed3dSBarry Smith PetscFunctionBegin; 25620700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2563c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2564c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2565c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2566c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2567c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2568c5eb9154SBarry Smith 2569ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2570ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2571ab54825eSJed Brown snes->abstol = abstol; 2572ab54825eSJed Brown } 2573ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2574ab54825eSJed 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); 2575ab54825eSJed Brown snes->rtol = rtol; 2576ab54825eSJed Brown } 2577ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2578ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2579c60f73f4SPeter Brune snes->stol = stol; 2580ab54825eSJed Brown } 2581ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2582ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2583ab54825eSJed Brown snes->max_its = maxit; 2584ab54825eSJed Brown } 2585ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2586ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2587ab54825eSJed Brown snes->max_funcs = maxf; 2588ab54825eSJed Brown } 258988976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 25903a40ed3dSBarry Smith PetscFunctionReturn(0); 25919b94acceSBarry Smith } 25929b94acceSBarry Smith 25934a2ae208SSatish Balay #undef __FUNCT__ 25944a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 25959b94acceSBarry Smith /*@ 259633174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 259733174efeSLois Curfman McInnes 2598c7afd0dbSLois Curfman McInnes Not Collective 2599c7afd0dbSLois Curfman McInnes 260033174efeSLois Curfman McInnes Input Parameters: 2601c7afd0dbSLois Curfman McInnes + snes - the SNES context 260285385478SLisandro Dalcin . atol - absolute convergence tolerance 260333174efeSLois Curfman McInnes . rtol - relative convergence tolerance 260433174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 260533174efeSLois Curfman McInnes of the change in the solution between steps 260633174efeSLois Curfman McInnes . maxit - maximum number of iterations 2607c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2608fee21e36SBarry Smith 260933174efeSLois Curfman McInnes Notes: 261033174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 261133174efeSLois Curfman McInnes 261236851e7fSLois Curfman McInnes Level: intermediate 261336851e7fSLois Curfman McInnes 261433174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 261533174efeSLois Curfman McInnes 261633174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 261733174efeSLois Curfman McInnes @*/ 26187087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 261933174efeSLois Curfman McInnes { 26203a40ed3dSBarry Smith PetscFunctionBegin; 26210700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 262285385478SLisandro Dalcin if (atol) *atol = snes->abstol; 262333174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 2624c60f73f4SPeter Brune if (stol) *stol = snes->stol; 262533174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 262633174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 26273a40ed3dSBarry Smith PetscFunctionReturn(0); 262833174efeSLois Curfman McInnes } 262933174efeSLois Curfman McInnes 26304a2ae208SSatish Balay #undef __FUNCT__ 26314a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 263233174efeSLois Curfman McInnes /*@ 26339b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 26349b94acceSBarry Smith 26353f9fe445SBarry Smith Logically Collective on SNES 2636fee21e36SBarry Smith 2637c7afd0dbSLois Curfman McInnes Input Parameters: 2638c7afd0dbSLois Curfman McInnes + snes - the SNES context 2639c7afd0dbSLois Curfman McInnes - tol - tolerance 2640c7afd0dbSLois Curfman McInnes 26419b94acceSBarry Smith Options Database Key: 2642c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 26439b94acceSBarry Smith 264436851e7fSLois Curfman McInnes Level: intermediate 264536851e7fSLois Curfman McInnes 26469b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 26479b94acceSBarry Smith 26482492ecdbSBarry Smith .seealso: SNESSetTolerances() 26499b94acceSBarry Smith @*/ 26507087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 26519b94acceSBarry Smith { 26523a40ed3dSBarry Smith PetscFunctionBegin; 26530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2654c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 26559b94acceSBarry Smith snes->deltatol = tol; 26563a40ed3dSBarry Smith PetscFunctionReturn(0); 26579b94acceSBarry Smith } 26589b94acceSBarry Smith 2659df9fa365SBarry Smith /* 2660df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2661df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2662df9fa365SBarry Smith macros instead of functions 2663df9fa365SBarry Smith */ 26644a2ae208SSatish Balay #undef __FUNCT__ 2665a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 26667087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2667ce1608b8SBarry Smith { 2668dfbe8321SBarry Smith PetscErrorCode ierr; 2669ce1608b8SBarry Smith 2670ce1608b8SBarry Smith PetscFunctionBegin; 26710700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2672a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2673ce1608b8SBarry Smith PetscFunctionReturn(0); 2674ce1608b8SBarry Smith } 2675ce1608b8SBarry Smith 26764a2ae208SSatish Balay #undef __FUNCT__ 2677a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 26787087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2679df9fa365SBarry Smith { 2680dfbe8321SBarry Smith PetscErrorCode ierr; 2681df9fa365SBarry Smith 2682df9fa365SBarry Smith PetscFunctionBegin; 2683a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2684df9fa365SBarry Smith PetscFunctionReturn(0); 2685df9fa365SBarry Smith } 2686df9fa365SBarry Smith 26874a2ae208SSatish Balay #undef __FUNCT__ 2688a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 26896bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2690df9fa365SBarry Smith { 2691dfbe8321SBarry Smith PetscErrorCode ierr; 2692df9fa365SBarry Smith 2693df9fa365SBarry Smith PetscFunctionBegin; 2694a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2695df9fa365SBarry Smith PetscFunctionReturn(0); 2696df9fa365SBarry Smith } 2697df9fa365SBarry Smith 26987087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2699b271bb04SBarry Smith #undef __FUNCT__ 2700b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 27017087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2702b271bb04SBarry Smith { 2703b271bb04SBarry Smith PetscDrawLG lg; 2704b271bb04SBarry Smith PetscErrorCode ierr; 2705b271bb04SBarry Smith PetscReal x,y,per; 2706b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2707b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2708b271bb04SBarry Smith PetscDraw draw; 2709b271bb04SBarry Smith PetscFunctionBegin; 2710b271bb04SBarry Smith if (!monctx) { 2711b271bb04SBarry Smith MPI_Comm comm; 2712b271bb04SBarry Smith 2713b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2714b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2715b271bb04SBarry Smith } 2716b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2717b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2718b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2719b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2720b271bb04SBarry Smith x = (PetscReal) n; 2721b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2722b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2723b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2724b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2725b271bb04SBarry Smith } 2726b271bb04SBarry Smith 2727b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2728b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2729b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2730b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2731b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2732b271bb04SBarry Smith x = (PetscReal) n; 2733b271bb04SBarry Smith y = 100.0*per; 2734b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2735b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2736b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2737b271bb04SBarry Smith } 2738b271bb04SBarry Smith 2739b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2740b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2741b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2742b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2743b271bb04SBarry Smith x = (PetscReal) n; 2744b271bb04SBarry Smith y = (prev - rnorm)/prev; 2745b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2746b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2747b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2748b271bb04SBarry Smith } 2749b271bb04SBarry Smith 2750b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2751b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2752b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2753b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2754b271bb04SBarry Smith x = (PetscReal) n; 2755b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2756b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2757b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2758b271bb04SBarry Smith } 2759b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2760b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2761b271bb04SBarry Smith } 2762b271bb04SBarry Smith prev = rnorm; 2763b271bb04SBarry Smith PetscFunctionReturn(0); 2764b271bb04SBarry Smith } 2765b271bb04SBarry Smith 2766b271bb04SBarry Smith #undef __FUNCT__ 2767b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 27687087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2769b271bb04SBarry Smith { 2770b271bb04SBarry Smith PetscErrorCode ierr; 2771b271bb04SBarry Smith 2772b271bb04SBarry Smith PetscFunctionBegin; 2773b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2774b271bb04SBarry Smith PetscFunctionReturn(0); 2775b271bb04SBarry Smith } 2776b271bb04SBarry Smith 2777b271bb04SBarry Smith #undef __FUNCT__ 2778b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 27796bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2780b271bb04SBarry Smith { 2781b271bb04SBarry Smith PetscErrorCode ierr; 2782b271bb04SBarry Smith 2783b271bb04SBarry Smith PetscFunctionBegin; 2784b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2785b271bb04SBarry Smith PetscFunctionReturn(0); 2786b271bb04SBarry Smith } 2787b271bb04SBarry Smith 27887a03ce2fSLisandro Dalcin #undef __FUNCT__ 27897a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 2790228d79bcSJed Brown /*@ 2791228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 2792228d79bcSJed Brown 2793228d79bcSJed Brown Collective on SNES 2794228d79bcSJed Brown 2795228d79bcSJed Brown Input Parameters: 2796228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 2797228d79bcSJed Brown . iter - iteration number 2798228d79bcSJed Brown - rnorm - relative norm of the residual 2799228d79bcSJed Brown 2800228d79bcSJed Brown Notes: 2801228d79bcSJed Brown This routine is called by the SNES implementations. 2802228d79bcSJed Brown It does not typically need to be called by the user. 2803228d79bcSJed Brown 2804228d79bcSJed Brown Level: developer 2805228d79bcSJed Brown 2806228d79bcSJed Brown .seealso: SNESMonitorSet() 2807228d79bcSJed Brown @*/ 28087a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 28097a03ce2fSLisandro Dalcin { 28107a03ce2fSLisandro Dalcin PetscErrorCode ierr; 28117a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 28127a03ce2fSLisandro Dalcin 28137a03ce2fSLisandro Dalcin PetscFunctionBegin; 28147a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 28157a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 28167a03ce2fSLisandro Dalcin } 28177a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 28187a03ce2fSLisandro Dalcin } 28197a03ce2fSLisandro Dalcin 28209b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 28219b94acceSBarry Smith 28224a2ae208SSatish Balay #undef __FUNCT__ 2823a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 28249b94acceSBarry Smith /*@C 2825a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 28269b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 28279b94acceSBarry Smith progress. 28289b94acceSBarry Smith 28293f9fe445SBarry Smith Logically Collective on SNES 2830fee21e36SBarry Smith 2831c7afd0dbSLois Curfman McInnes Input Parameters: 2832c7afd0dbSLois Curfman McInnes + snes - the SNES context 2833c7afd0dbSLois Curfman McInnes . func - monitoring routine 2834b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 2835e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 2836b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 2837b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 28389b94acceSBarry Smith 2839c7afd0dbSLois Curfman McInnes Calling sequence of func: 2840a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2841c7afd0dbSLois Curfman McInnes 2842c7afd0dbSLois Curfman McInnes + snes - the SNES context 2843c7afd0dbSLois Curfman McInnes . its - iteration number 2844c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 284540a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 28469b94acceSBarry Smith 28479665c990SLois Curfman McInnes Options Database Keys: 2848a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 2849a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 2850a6570f20SBarry Smith uses SNESMonitorLGCreate() 2851cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 2852c7afd0dbSLois Curfman McInnes been hardwired into a code by 2853a6570f20SBarry Smith calls to SNESMonitorSet(), but 2854c7afd0dbSLois Curfman McInnes does not cancel those set via 2855c7afd0dbSLois Curfman McInnes the options database. 28569665c990SLois Curfman McInnes 2857639f9d9dSBarry Smith Notes: 28586bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 2859a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 28606bc08f3fSLois Curfman McInnes order in which they were set. 2861639f9d9dSBarry Smith 2862025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 2863025f1a04SBarry Smith 286436851e7fSLois Curfman McInnes Level: intermediate 286536851e7fSLois Curfman McInnes 28669b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 28679b94acceSBarry Smith 2868a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 28699b94acceSBarry Smith @*/ 2870c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 28719b94acceSBarry Smith { 2872b90d0a6eSBarry Smith PetscInt i; 2873649052a6SBarry Smith PetscErrorCode ierr; 2874b90d0a6eSBarry Smith 28753a40ed3dSBarry Smith PetscFunctionBegin; 28760700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 287717186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2878b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 2879649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 2880649052a6SBarry Smith if (monitordestroy) { 2881c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 2882649052a6SBarry Smith } 2883b90d0a6eSBarry Smith PetscFunctionReturn(0); 2884b90d0a6eSBarry Smith } 2885b90d0a6eSBarry Smith } 2886b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 2887b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 2888639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 28893a40ed3dSBarry Smith PetscFunctionReturn(0); 28909b94acceSBarry Smith } 28919b94acceSBarry Smith 28924a2ae208SSatish Balay #undef __FUNCT__ 2893a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 28945cd90555SBarry Smith /*@C 2895a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 28965cd90555SBarry Smith 28973f9fe445SBarry Smith Logically Collective on SNES 2898c7afd0dbSLois Curfman McInnes 28995cd90555SBarry Smith Input Parameters: 29005cd90555SBarry Smith . snes - the SNES context 29015cd90555SBarry Smith 29021a480d89SAdministrator Options Database Key: 2903a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 2904a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 2905c7afd0dbSLois Curfman McInnes set via the options database 29065cd90555SBarry Smith 29075cd90555SBarry Smith Notes: 29085cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 29095cd90555SBarry Smith 291036851e7fSLois Curfman McInnes Level: intermediate 291136851e7fSLois Curfman McInnes 29125cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 29135cd90555SBarry Smith 2914a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 29155cd90555SBarry Smith @*/ 29167087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 29175cd90555SBarry Smith { 2918d952e501SBarry Smith PetscErrorCode ierr; 2919d952e501SBarry Smith PetscInt i; 2920d952e501SBarry Smith 29215cd90555SBarry Smith PetscFunctionBegin; 29220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2923d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 2924d952e501SBarry Smith if (snes->monitordestroy[i]) { 29253c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 2926d952e501SBarry Smith } 2927d952e501SBarry Smith } 29285cd90555SBarry Smith snes->numbermonitors = 0; 29295cd90555SBarry Smith PetscFunctionReturn(0); 29305cd90555SBarry Smith } 29315cd90555SBarry Smith 29324a2ae208SSatish Balay #undef __FUNCT__ 29334a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 29349b94acceSBarry Smith /*@C 29359b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 29369b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 29379b94acceSBarry Smith 29383f9fe445SBarry Smith Logically Collective on SNES 2939fee21e36SBarry Smith 2940c7afd0dbSLois Curfman McInnes Input Parameters: 2941c7afd0dbSLois Curfman McInnes + snes - the SNES context 2942c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 29437f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 29447f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 29459b94acceSBarry Smith 2946c7afd0dbSLois Curfman McInnes Calling sequence of func: 294706ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 2948c7afd0dbSLois Curfman McInnes 2949c7afd0dbSLois Curfman McInnes + snes - the SNES context 295006ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 2951c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 2952184914b5SBarry Smith . reason - reason for convergence/divergence 2953c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 29544b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 29554b27c08aSLois Curfman McInnes - f - 2-norm of function 29569b94acceSBarry Smith 295736851e7fSLois Curfman McInnes Level: advanced 295836851e7fSLois Curfman McInnes 29599b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 29609b94acceSBarry Smith 296185385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 29629b94acceSBarry Smith @*/ 29637087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 29649b94acceSBarry Smith { 29657f7931b9SBarry Smith PetscErrorCode ierr; 29667f7931b9SBarry Smith 29673a40ed3dSBarry Smith PetscFunctionBegin; 29680700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 296985385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 29707f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 29717f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 29727f7931b9SBarry Smith } 297385385478SLisandro Dalcin snes->ops->converged = func; 29747f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 297585385478SLisandro Dalcin snes->cnvP = cctx; 29763a40ed3dSBarry Smith PetscFunctionReturn(0); 29779b94acceSBarry Smith } 29789b94acceSBarry Smith 29794a2ae208SSatish Balay #undef __FUNCT__ 29804a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 298152baeb72SSatish Balay /*@ 2982184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 2983184914b5SBarry Smith 2984184914b5SBarry Smith Not Collective 2985184914b5SBarry Smith 2986184914b5SBarry Smith Input Parameter: 2987184914b5SBarry Smith . snes - the SNES context 2988184914b5SBarry Smith 2989184914b5SBarry Smith Output Parameter: 29904d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 2991184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 2992184914b5SBarry Smith 2993184914b5SBarry Smith Level: intermediate 2994184914b5SBarry Smith 2995184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 2996184914b5SBarry Smith 2997184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 2998184914b5SBarry Smith 299985385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 3000184914b5SBarry Smith @*/ 30017087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 3002184914b5SBarry Smith { 3003184914b5SBarry Smith PetscFunctionBegin; 30040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 30054482741eSBarry Smith PetscValidPointer(reason,2); 3006184914b5SBarry Smith *reason = snes->reason; 3007184914b5SBarry Smith PetscFunctionReturn(0); 3008184914b5SBarry Smith } 3009184914b5SBarry Smith 30104a2ae208SSatish Balay #undef __FUNCT__ 30114a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 3012c9005455SLois Curfman McInnes /*@ 3013c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 3014c9005455SLois Curfman McInnes 30153f9fe445SBarry Smith Logically Collective on SNES 3016fee21e36SBarry Smith 3017c7afd0dbSLois Curfman McInnes Input Parameters: 3018c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 30198c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 3020cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 3021758f92a0SBarry Smith . na - size of a and its 302264731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 3023758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 3024c7afd0dbSLois Curfman McInnes 3025308dcc3eSBarry Smith Notes: 3026308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 3027308dcc3eSBarry Smith default array of length 10000 is allocated. 3028308dcc3eSBarry Smith 3029c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 3030c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 3031c9005455SLois Curfman McInnes during the section of code that is being timed. 3032c9005455SLois Curfman McInnes 303336851e7fSLois Curfman McInnes Level: intermediate 303436851e7fSLois Curfman McInnes 3035c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 3036758f92a0SBarry Smith 303708405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 3038758f92a0SBarry Smith 3039c9005455SLois Curfman McInnes @*/ 30407087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 3041c9005455SLois Curfman McInnes { 3042308dcc3eSBarry Smith PetscErrorCode ierr; 3043308dcc3eSBarry Smith 30443a40ed3dSBarry Smith PetscFunctionBegin; 30450700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 30464482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 3047a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 3048308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 3049308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 3050308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 3051308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 3052308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 3053308dcc3eSBarry Smith } 3054c9005455SLois Curfman McInnes snes->conv_hist = a; 3055758f92a0SBarry Smith snes->conv_hist_its = its; 3056758f92a0SBarry Smith snes->conv_hist_max = na; 3057a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 3058758f92a0SBarry Smith snes->conv_hist_reset = reset; 3059758f92a0SBarry Smith PetscFunctionReturn(0); 3060758f92a0SBarry Smith } 3061758f92a0SBarry Smith 3062308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3063c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 3064c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 3065308dcc3eSBarry Smith EXTERN_C_BEGIN 3066308dcc3eSBarry Smith #undef __FUNCT__ 3067308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 3068308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3069308dcc3eSBarry Smith { 3070308dcc3eSBarry Smith mxArray *mat; 3071308dcc3eSBarry Smith PetscInt i; 3072308dcc3eSBarry Smith PetscReal *ar; 3073308dcc3eSBarry Smith 3074308dcc3eSBarry Smith PetscFunctionBegin; 3075308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3076308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3077308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 3078308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 3079308dcc3eSBarry Smith } 3080308dcc3eSBarry Smith PetscFunctionReturn(mat); 3081308dcc3eSBarry Smith } 3082308dcc3eSBarry Smith EXTERN_C_END 3083308dcc3eSBarry Smith #endif 3084308dcc3eSBarry Smith 3085308dcc3eSBarry Smith 30864a2ae208SSatish Balay #undef __FUNCT__ 30874a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 30880c4c9dddSBarry Smith /*@C 3089758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3090758f92a0SBarry Smith 30913f9fe445SBarry Smith Not Collective 3092758f92a0SBarry Smith 3093758f92a0SBarry Smith Input Parameter: 3094758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3095758f92a0SBarry Smith 3096758f92a0SBarry Smith Output Parameters: 3097758f92a0SBarry Smith . a - array to hold history 3098758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3099758f92a0SBarry Smith negative if not converged) for each solve. 3100758f92a0SBarry Smith - na - size of a and its 3101758f92a0SBarry Smith 3102758f92a0SBarry Smith Notes: 3103758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3104758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3105758f92a0SBarry Smith 3106758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3107758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3108758f92a0SBarry Smith during the section of code that is being timed. 3109758f92a0SBarry Smith 3110758f92a0SBarry Smith Level: intermediate 3111758f92a0SBarry Smith 3112758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3113758f92a0SBarry Smith 3114758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3115758f92a0SBarry Smith 3116758f92a0SBarry Smith @*/ 31177087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3118758f92a0SBarry Smith { 3119758f92a0SBarry Smith PetscFunctionBegin; 31200700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3121758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3122758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3123758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 31243a40ed3dSBarry Smith PetscFunctionReturn(0); 3125c9005455SLois Curfman McInnes } 3126c9005455SLois Curfman McInnes 3127e74ef692SMatthew Knepley #undef __FUNCT__ 3128e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 3129ac226902SBarry Smith /*@C 313076b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3131eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 31327e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 313376b2cf59SMatthew Knepley 31343f9fe445SBarry Smith Logically Collective on SNES 313576b2cf59SMatthew Knepley 313676b2cf59SMatthew Knepley Input Parameters: 313776b2cf59SMatthew Knepley . snes - The nonlinear solver context 313876b2cf59SMatthew Knepley . func - The function 313976b2cf59SMatthew Knepley 314076b2cf59SMatthew Knepley Calling sequence of func: 3141b5d30489SBarry Smith . func (SNES snes, PetscInt step); 314276b2cf59SMatthew Knepley 314376b2cf59SMatthew Knepley . step - The current step of the iteration 314476b2cf59SMatthew Knepley 3145fe97e370SBarry Smith Level: advanced 3146fe97e370SBarry Smith 3147fe97e370SBarry 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() 3148fe97e370SBarry Smith This is not used by most users. 314976b2cf59SMatthew Knepley 315076b2cf59SMatthew Knepley .keywords: SNES, update 3151b5d30489SBarry Smith 315285385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 315376b2cf59SMatthew Knepley @*/ 31547087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 315576b2cf59SMatthew Knepley { 315676b2cf59SMatthew Knepley PetscFunctionBegin; 31570700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3158e7788613SBarry Smith snes->ops->update = func; 315976b2cf59SMatthew Knepley PetscFunctionReturn(0); 316076b2cf59SMatthew Knepley } 316176b2cf59SMatthew Knepley 3162e74ef692SMatthew Knepley #undef __FUNCT__ 3163e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 316476b2cf59SMatthew Knepley /*@ 316576b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 316676b2cf59SMatthew Knepley 316776b2cf59SMatthew Knepley Not collective 316876b2cf59SMatthew Knepley 316976b2cf59SMatthew Knepley Input Parameters: 317076b2cf59SMatthew Knepley . snes - The nonlinear solver context 317176b2cf59SMatthew Knepley . step - The current step of the iteration 317276b2cf59SMatthew Knepley 3173205452f4SMatthew Knepley Level: intermediate 3174205452f4SMatthew Knepley 317576b2cf59SMatthew Knepley .keywords: SNES, update 3176a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 317776b2cf59SMatthew Knepley @*/ 31787087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 317976b2cf59SMatthew Knepley { 318076b2cf59SMatthew Knepley PetscFunctionBegin; 318176b2cf59SMatthew Knepley PetscFunctionReturn(0); 318276b2cf59SMatthew Knepley } 318376b2cf59SMatthew Knepley 31844a2ae208SSatish Balay #undef __FUNCT__ 31854a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 31869b94acceSBarry Smith /* 31879b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 31889b94acceSBarry Smith positive parameter delta. 31899b94acceSBarry Smith 31909b94acceSBarry Smith Input Parameters: 3191c7afd0dbSLois Curfman McInnes + snes - the SNES context 31929b94acceSBarry Smith . y - approximate solution of linear system 31939b94acceSBarry Smith . fnorm - 2-norm of current function 3194c7afd0dbSLois Curfman McInnes - delta - trust region size 31959b94acceSBarry Smith 31969b94acceSBarry Smith Output Parameters: 3197c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 31989b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 31999b94acceSBarry Smith region, and exceeds zero otherwise. 3200c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 32019b94acceSBarry Smith 32029b94acceSBarry Smith Note: 32034b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 32049b94acceSBarry Smith is set to be the maximum allowable step size. 32059b94acceSBarry Smith 32069b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 32079b94acceSBarry Smith */ 3208dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 32099b94acceSBarry Smith { 3210064f8208SBarry Smith PetscReal nrm; 3211ea709b57SSatish Balay PetscScalar cnorm; 3212dfbe8321SBarry Smith PetscErrorCode ierr; 32133a40ed3dSBarry Smith 32143a40ed3dSBarry Smith PetscFunctionBegin; 32150700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 32160700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3217c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3218184914b5SBarry Smith 3219064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3220064f8208SBarry Smith if (nrm > *delta) { 3221064f8208SBarry Smith nrm = *delta/nrm; 3222064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3223064f8208SBarry Smith cnorm = nrm; 32242dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 32259b94acceSBarry Smith *ynorm = *delta; 32269b94acceSBarry Smith } else { 32279b94acceSBarry Smith *gpnorm = 0.0; 3228064f8208SBarry Smith *ynorm = nrm; 32299b94acceSBarry Smith } 32303a40ed3dSBarry Smith PetscFunctionReturn(0); 32319b94acceSBarry Smith } 32329b94acceSBarry Smith 32334a2ae208SSatish Balay #undef __FUNCT__ 32344a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 32356ce558aeSBarry Smith /*@C 3236f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3237f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 32389b94acceSBarry Smith 3239c7afd0dbSLois Curfman McInnes Collective on SNES 3240c7afd0dbSLois Curfman McInnes 3241b2002411SLois Curfman McInnes Input Parameters: 3242c7afd0dbSLois Curfman McInnes + snes - the SNES context 32433cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 324485385478SLisandro Dalcin - x - the solution vector. 32459b94acceSBarry Smith 3246b2002411SLois Curfman McInnes Notes: 32478ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 32488ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 32498ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 32508ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 32518ddd3da0SLois Curfman McInnes 325236851e7fSLois Curfman McInnes Level: beginner 325336851e7fSLois Curfman McInnes 32549b94acceSBarry Smith .keywords: SNES, nonlinear, solve 32559b94acceSBarry Smith 3256c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 32579b94acceSBarry Smith @*/ 32587087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 32599b94acceSBarry Smith { 3260dfbe8321SBarry Smith PetscErrorCode ierr; 3261ace3abfcSBarry Smith PetscBool flg; 3262eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 3263eabae89aSBarry Smith PetscViewer viewer; 3264efd51863SBarry Smith PetscInt grid; 3265a69afd8bSBarry Smith Vec xcreated = PETSC_NULL; 3266caa4e7f2SJed Brown DM dm; 3267052efed2SBarry Smith 32683a40ed3dSBarry Smith PetscFunctionBegin; 32690700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3270a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3271a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 32720700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 327385385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 327485385478SLisandro Dalcin 3275caa4e7f2SJed Brown if (!x) { 3276caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3277caa4e7f2SJed Brown ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 3278a69afd8bSBarry Smith x = xcreated; 3279a69afd8bSBarry Smith } 3280a69afd8bSBarry Smith 3281a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3282efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3283efd51863SBarry Smith 328485385478SLisandro Dalcin /* set solution vector */ 3285efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 32866bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 328785385478SLisandro Dalcin snes->vec_sol = x; 3288caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3289caa4e7f2SJed Brown 3290caa4e7f2SJed Brown /* set affine vector if provided */ 329185385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 32926bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 329385385478SLisandro Dalcin snes->vec_rhs = b; 329485385478SLisandro Dalcin 329570e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 32963f149594SLisandro Dalcin 32977eee914bSBarry Smith if (!grid) { 32987eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3299d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3300dd568438SSatish Balay } else if (snes->dm) { 3301dd568438SSatish Balay PetscBool ig; 3302dd568438SSatish Balay ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr); 3303dd568438SSatish Balay if (ig) { 33047eee914bSBarry Smith ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr); 33057eee914bSBarry Smith } 3306d25893d9SBarry Smith } 3307dd568438SSatish Balay } 3308d25893d9SBarry Smith 3309abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 331050ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3311d5e45103SBarry Smith 33123f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 33134936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 331485385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 33154936397dSBarry Smith if (snes->domainerror){ 33164936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 33174936397dSBarry Smith snes->domainerror = PETSC_FALSE; 33184936397dSBarry Smith } 331917186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 33203f149594SLisandro Dalcin 33217adad957SLisandro Dalcin ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 3322eabae89aSBarry Smith if (flg && !PetscPreLoadingOn) { 33237adad957SLisandro Dalcin ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 3324eabae89aSBarry Smith ierr = SNESView(snes,viewer);CHKERRQ(ierr); 33256bf464f9SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3326eabae89aSBarry Smith } 3327eabae89aSBarry Smith 332890d69ab7SBarry Smith flg = PETSC_FALSE; 3329acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3330da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 33315968eb51SBarry Smith if (snes->printreason) { 3332a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 33335968eb51SBarry Smith if (snes->reason > 0) { 3334c7e7b494SJed 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); 33355968eb51SBarry Smith } else { 3336c7e7b494SJed 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); 33375968eb51SBarry Smith } 3338a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 33395968eb51SBarry Smith } 33405968eb51SBarry Smith 33418501fc72SJed Brown flg = PETSC_FALSE; 33428501fc72SJed Brown ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 33438501fc72SJed Brown if (flg) { 33448501fc72SJed Brown PetscViewer viewer; 33458501fc72SJed Brown ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 33468501fc72SJed Brown ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 33478501fc72SJed Brown ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 33488501fc72SJed Brown ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 33498501fc72SJed Brown ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 33508501fc72SJed Brown } 33518501fc72SJed Brown 3352e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3353efd51863SBarry Smith if (grid < snes->gridsequence) { 3354efd51863SBarry Smith DM fine; 3355efd51863SBarry Smith Vec xnew; 3356efd51863SBarry Smith Mat interp; 3357efd51863SBarry Smith 3358efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3359c5c77316SJed Brown if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 3360e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3361efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3362efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3363efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3364efd51863SBarry Smith x = xnew; 3365efd51863SBarry Smith 3366efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3367efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3368efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3369a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3370efd51863SBarry Smith } 3371efd51863SBarry Smith } 3372a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 33733a40ed3dSBarry Smith PetscFunctionReturn(0); 33749b94acceSBarry Smith } 33759b94acceSBarry Smith 33769b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 33779b94acceSBarry Smith 33784a2ae208SSatish Balay #undef __FUNCT__ 33794a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 338082bf6240SBarry Smith /*@C 33814b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 33829b94acceSBarry Smith 3383fee21e36SBarry Smith Collective on SNES 3384fee21e36SBarry Smith 3385c7afd0dbSLois Curfman McInnes Input Parameters: 3386c7afd0dbSLois Curfman McInnes + snes - the SNES context 3387454a90a3SBarry Smith - type - a known method 3388c7afd0dbSLois Curfman McInnes 3389c7afd0dbSLois Curfman McInnes Options Database Key: 3390454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3391c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3392ae12b187SLois Curfman McInnes 33939b94acceSBarry Smith Notes: 3394e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 33954b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3396c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 33974b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3398c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 33999b94acceSBarry Smith 3400ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3401ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3402ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3403ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3404ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3405ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3406ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3407ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3408ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3409b0a32e0cSBarry Smith appropriate method. 341036851e7fSLois Curfman McInnes 341136851e7fSLois Curfman McInnes Level: intermediate 3412a703fe33SLois Curfman McInnes 3413454a90a3SBarry Smith .keywords: SNES, set, type 3414435da068SBarry Smith 3415435da068SBarry Smith .seealso: SNESType, SNESCreate() 3416435da068SBarry Smith 34179b94acceSBarry Smith @*/ 34187087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 34199b94acceSBarry Smith { 3420dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3421ace3abfcSBarry Smith PetscBool match; 34223a40ed3dSBarry Smith 34233a40ed3dSBarry Smith PetscFunctionBegin; 34240700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34254482741eSBarry Smith PetscValidCharPointer(type,2); 342682bf6240SBarry Smith 34276831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 34280f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 342992ff6ae8SBarry Smith 34304b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3431e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 343275396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 3433b5c23020SJed Brown if (snes->ops->destroy) { 3434b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 3435b5c23020SJed Brown snes->ops->destroy = PETSC_NULL; 3436b5c23020SJed Brown } 343775396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 343875396ef9SLisandro Dalcin snes->ops->setup = 0; 343975396ef9SLisandro Dalcin snes->ops->solve = 0; 344075396ef9SLisandro Dalcin snes->ops->view = 0; 344175396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 344275396ef9SLisandro Dalcin snes->ops->destroy = 0; 344375396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 344475396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3445454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 344603bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 34479fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 34489fb22e1aSBarry Smith if (PetscAMSPublishAll) { 34499fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 34509fb22e1aSBarry Smith } 34519fb22e1aSBarry Smith #endif 34523a40ed3dSBarry Smith PetscFunctionReturn(0); 34539b94acceSBarry Smith } 34549b94acceSBarry Smith 3455a847f771SSatish Balay 34569b94acceSBarry Smith /* --------------------------------------------------------------------- */ 34574a2ae208SSatish Balay #undef __FUNCT__ 34584a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 345952baeb72SSatish Balay /*@ 34609b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3461f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 34629b94acceSBarry Smith 3463fee21e36SBarry Smith Not Collective 3464fee21e36SBarry Smith 346536851e7fSLois Curfman McInnes Level: advanced 346636851e7fSLois Curfman McInnes 34679b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 34689b94acceSBarry Smith 34699b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 34709b94acceSBarry Smith @*/ 34717087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 34729b94acceSBarry Smith { 3473dfbe8321SBarry Smith PetscErrorCode ierr; 347482bf6240SBarry Smith 34753a40ed3dSBarry Smith PetscFunctionBegin; 34761441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 34774c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 34783a40ed3dSBarry Smith PetscFunctionReturn(0); 34799b94acceSBarry Smith } 34809b94acceSBarry Smith 34814a2ae208SSatish Balay #undef __FUNCT__ 34824a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 34839b94acceSBarry Smith /*@C 34849a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 34859b94acceSBarry Smith 3486c7afd0dbSLois Curfman McInnes Not Collective 3487c7afd0dbSLois Curfman McInnes 34889b94acceSBarry Smith Input Parameter: 34894b0e389bSBarry Smith . snes - nonlinear solver context 34909b94acceSBarry Smith 34919b94acceSBarry Smith Output Parameter: 34923a7fca6bSBarry Smith . type - SNES method (a character string) 34939b94acceSBarry Smith 349436851e7fSLois Curfman McInnes Level: intermediate 349536851e7fSLois Curfman McInnes 3496454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 34979b94acceSBarry Smith @*/ 34987087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 34999b94acceSBarry Smith { 35003a40ed3dSBarry Smith PetscFunctionBegin; 35010700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35024482741eSBarry Smith PetscValidPointer(type,2); 35037adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 35043a40ed3dSBarry Smith PetscFunctionReturn(0); 35059b94acceSBarry Smith } 35069b94acceSBarry Smith 35074a2ae208SSatish Balay #undef __FUNCT__ 35084a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 350952baeb72SSatish Balay /*@ 35109b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3511c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 35129b94acceSBarry Smith 3513c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3514c7afd0dbSLois Curfman McInnes 35159b94acceSBarry Smith Input Parameter: 35169b94acceSBarry Smith . snes - the SNES context 35179b94acceSBarry Smith 35189b94acceSBarry Smith Output Parameter: 35199b94acceSBarry Smith . x - the solution 35209b94acceSBarry Smith 352170e92668SMatthew Knepley Level: intermediate 352236851e7fSLois Curfman McInnes 35239b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 35249b94acceSBarry Smith 352585385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 35269b94acceSBarry Smith @*/ 35277087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 35289b94acceSBarry Smith { 35293a40ed3dSBarry Smith PetscFunctionBegin; 35300700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35314482741eSBarry Smith PetscValidPointer(x,2); 353285385478SLisandro Dalcin *x = snes->vec_sol; 353370e92668SMatthew Knepley PetscFunctionReturn(0); 353470e92668SMatthew Knepley } 353570e92668SMatthew Knepley 353670e92668SMatthew Knepley #undef __FUNCT__ 35374a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 353852baeb72SSatish Balay /*@ 35399b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 35409b94acceSBarry Smith stored. 35419b94acceSBarry Smith 3542c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3543c7afd0dbSLois Curfman McInnes 35449b94acceSBarry Smith Input Parameter: 35459b94acceSBarry Smith . snes - the SNES context 35469b94acceSBarry Smith 35479b94acceSBarry Smith Output Parameter: 35489b94acceSBarry Smith . x - the solution update 35499b94acceSBarry Smith 355036851e7fSLois Curfman McInnes Level: advanced 355136851e7fSLois Curfman McInnes 35529b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 35539b94acceSBarry Smith 355485385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 35559b94acceSBarry Smith @*/ 35567087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 35579b94acceSBarry Smith { 35583a40ed3dSBarry Smith PetscFunctionBegin; 35590700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35604482741eSBarry Smith PetscValidPointer(x,2); 356185385478SLisandro Dalcin *x = snes->vec_sol_update; 35623a40ed3dSBarry Smith PetscFunctionReturn(0); 35639b94acceSBarry Smith } 35649b94acceSBarry Smith 35654a2ae208SSatish Balay #undef __FUNCT__ 35664a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 35679b94acceSBarry Smith /*@C 35683638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 35699b94acceSBarry Smith 3570a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 3571c7afd0dbSLois Curfman McInnes 35729b94acceSBarry Smith Input Parameter: 35739b94acceSBarry Smith . snes - the SNES context 35749b94acceSBarry Smith 35759b94acceSBarry Smith Output Parameter: 35767bf4e008SBarry Smith + r - the function (or PETSC_NULL) 357770e92668SMatthew Knepley . func - the function (or PETSC_NULL) 357870e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 35799b94acceSBarry Smith 358036851e7fSLois Curfman McInnes Level: advanced 358136851e7fSLois Curfman McInnes 3582a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 35839b94acceSBarry Smith 35844b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 35859b94acceSBarry Smith @*/ 35867087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 35879b94acceSBarry Smith { 3588a63bb30eSJed Brown PetscErrorCode ierr; 35896cab3a1bSJed Brown DM dm; 3590a63bb30eSJed Brown 35913a40ed3dSBarry Smith PetscFunctionBegin; 35920700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3593a63bb30eSJed Brown if (r) { 3594a63bb30eSJed Brown if (!snes->vec_func) { 3595a63bb30eSJed Brown if (snes->vec_rhs) { 3596a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 3597a63bb30eSJed Brown } else if (snes->vec_sol) { 3598a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 3599a63bb30eSJed Brown } else if (snes->dm) { 3600a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 3601a63bb30eSJed Brown } 3602a63bb30eSJed Brown } 3603a63bb30eSJed Brown *r = snes->vec_func; 3604a63bb30eSJed Brown } 36056cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 36066cab3a1bSJed Brown ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr); 36073a40ed3dSBarry Smith PetscFunctionReturn(0); 36089b94acceSBarry Smith } 36099b94acceSBarry Smith 3610c79ef259SPeter Brune /*@C 3611c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3612c79ef259SPeter Brune 3613c79ef259SPeter Brune Input Parameter: 3614c79ef259SPeter Brune . snes - the SNES context 3615c79ef259SPeter Brune 3616c79ef259SPeter Brune Output Parameter: 3617c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3618c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3619c79ef259SPeter Brune 3620c79ef259SPeter Brune Level: advanced 3621c79ef259SPeter Brune 3622c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3623c79ef259SPeter Brune 3624c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3625c79ef259SPeter Brune @*/ 3626c79ef259SPeter Brune 36274a2ae208SSatish Balay #undef __FUNCT__ 3628646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3629646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3630646217ecSPeter Brune { 36316cab3a1bSJed Brown PetscErrorCode ierr; 36326cab3a1bSJed Brown DM dm; 36336cab3a1bSJed Brown 3634646217ecSPeter Brune PetscFunctionBegin; 3635646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36366cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 36376cab3a1bSJed Brown ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr); 3638646217ecSPeter Brune PetscFunctionReturn(0); 3639646217ecSPeter Brune } 3640646217ecSPeter Brune 36414a2ae208SSatish Balay #undef __FUNCT__ 36424a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 36433c7409f5SSatish Balay /*@C 36443c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3645d850072dSLois Curfman McInnes SNES options in the database. 36463c7409f5SSatish Balay 36473f9fe445SBarry Smith Logically Collective on SNES 3648fee21e36SBarry Smith 3649c7afd0dbSLois Curfman McInnes Input Parameter: 3650c7afd0dbSLois Curfman McInnes + snes - the SNES context 3651c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3652c7afd0dbSLois Curfman McInnes 3653d850072dSLois Curfman McInnes Notes: 3654a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3655c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3656d850072dSLois Curfman McInnes 365736851e7fSLois Curfman McInnes Level: advanced 365836851e7fSLois Curfman McInnes 36593c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3660a86d99e1SLois Curfman McInnes 3661a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 36623c7409f5SSatish Balay @*/ 36637087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 36643c7409f5SSatish Balay { 3665dfbe8321SBarry Smith PetscErrorCode ierr; 36663c7409f5SSatish Balay 36673a40ed3dSBarry Smith PetscFunctionBegin; 36680700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3669639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 36701cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 367194b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 36723a40ed3dSBarry Smith PetscFunctionReturn(0); 36733c7409f5SSatish Balay } 36743c7409f5SSatish Balay 36754a2ae208SSatish Balay #undef __FUNCT__ 36764a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 36773c7409f5SSatish Balay /*@C 3678f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3679d850072dSLois Curfman McInnes SNES options in the database. 36803c7409f5SSatish Balay 36813f9fe445SBarry Smith Logically Collective on SNES 3682fee21e36SBarry Smith 3683c7afd0dbSLois Curfman McInnes Input Parameters: 3684c7afd0dbSLois Curfman McInnes + snes - the SNES context 3685c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3686c7afd0dbSLois Curfman McInnes 3687d850072dSLois Curfman McInnes Notes: 3688a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3689c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3690d850072dSLois Curfman McInnes 369136851e7fSLois Curfman McInnes Level: advanced 369236851e7fSLois Curfman McInnes 36933c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3694a86d99e1SLois Curfman McInnes 3695a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 36963c7409f5SSatish Balay @*/ 36977087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 36983c7409f5SSatish Balay { 3699dfbe8321SBarry Smith PetscErrorCode ierr; 37003c7409f5SSatish Balay 37013a40ed3dSBarry Smith PetscFunctionBegin; 37020700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3703639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 37041cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 370594b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 37063a40ed3dSBarry Smith PetscFunctionReturn(0); 37073c7409f5SSatish Balay } 37083c7409f5SSatish Balay 37094a2ae208SSatish Balay #undef __FUNCT__ 37104a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 37119ab63eb5SSatish Balay /*@C 37123c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 37133c7409f5SSatish Balay SNES options in the database. 37143c7409f5SSatish Balay 3715c7afd0dbSLois Curfman McInnes Not Collective 3716c7afd0dbSLois Curfman McInnes 37173c7409f5SSatish Balay Input Parameter: 37183c7409f5SSatish Balay . snes - the SNES context 37193c7409f5SSatish Balay 37203c7409f5SSatish Balay Output Parameter: 37213c7409f5SSatish Balay . prefix - pointer to the prefix string used 37223c7409f5SSatish Balay 37234ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 37249ab63eb5SSatish Balay sufficient length to hold the prefix. 37259ab63eb5SSatish Balay 372636851e7fSLois Curfman McInnes Level: advanced 372736851e7fSLois Curfman McInnes 37283c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 3729a86d99e1SLois Curfman McInnes 3730a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 37313c7409f5SSatish Balay @*/ 37327087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 37333c7409f5SSatish Balay { 3734dfbe8321SBarry Smith PetscErrorCode ierr; 37353c7409f5SSatish Balay 37363a40ed3dSBarry Smith PetscFunctionBegin; 37370700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3738639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 37393a40ed3dSBarry Smith PetscFunctionReturn(0); 37403c7409f5SSatish Balay } 37413c7409f5SSatish Balay 3742b2002411SLois Curfman McInnes 37434a2ae208SSatish Balay #undef __FUNCT__ 37444a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 37453cea93caSBarry Smith /*@C 37463cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 37473cea93caSBarry Smith 37487f6c08e0SMatthew Knepley Level: advanced 37493cea93caSBarry Smith @*/ 37507087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3751b2002411SLois Curfman McInnes { 3752e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3753dfbe8321SBarry Smith PetscErrorCode ierr; 3754b2002411SLois Curfman McInnes 3755b2002411SLois Curfman McInnes PetscFunctionBegin; 3756b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3757c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3758b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3759b2002411SLois Curfman McInnes } 3760da9b6338SBarry Smith 3761da9b6338SBarry Smith #undef __FUNCT__ 3762da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 37637087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3764da9b6338SBarry Smith { 3765dfbe8321SBarry Smith PetscErrorCode ierr; 376677431f27SBarry Smith PetscInt N,i,j; 3767da9b6338SBarry Smith Vec u,uh,fh; 3768da9b6338SBarry Smith PetscScalar value; 3769da9b6338SBarry Smith PetscReal norm; 3770da9b6338SBarry Smith 3771da9b6338SBarry Smith PetscFunctionBegin; 3772da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3773da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3774da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3775da9b6338SBarry Smith 3776da9b6338SBarry Smith /* currently only works for sequential */ 3777da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3778da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3779da9b6338SBarry Smith for (i=0; i<N; i++) { 3780da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 378177431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3782da9b6338SBarry Smith for (j=-10; j<11; j++) { 3783ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3784da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 37853ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3786da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 378777431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3788da9b6338SBarry Smith value = -value; 3789da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3790da9b6338SBarry Smith } 3791da9b6338SBarry Smith } 37926bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 37936bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 3794da9b6338SBarry Smith PetscFunctionReturn(0); 3795da9b6338SBarry Smith } 379671f87433Sdalcinl 379771f87433Sdalcinl #undef __FUNCT__ 3798fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 379971f87433Sdalcinl /*@ 3800fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 380171f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 380271f87433Sdalcinl Newton method. 380371f87433Sdalcinl 38043f9fe445SBarry Smith Logically Collective on SNES 380571f87433Sdalcinl 380671f87433Sdalcinl Input Parameters: 380771f87433Sdalcinl + snes - SNES context 380871f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 380971f87433Sdalcinl 381064ba62caSBarry Smith Options Database: 381164ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 381264ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 381364ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 381464ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 381564ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 381664ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 381764ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 381864ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 381964ba62caSBarry Smith 382071f87433Sdalcinl Notes: 382171f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 382271f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 382371f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 382471f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 382571f87433Sdalcinl solver. 382671f87433Sdalcinl 382771f87433Sdalcinl Level: advanced 382871f87433Sdalcinl 382971f87433Sdalcinl Reference: 383071f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 383171f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 383271f87433Sdalcinl 383371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 383471f87433Sdalcinl 3835fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 383671f87433Sdalcinl @*/ 38377087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 383871f87433Sdalcinl { 383971f87433Sdalcinl PetscFunctionBegin; 38400700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3841acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 384271f87433Sdalcinl snes->ksp_ewconv = flag; 384371f87433Sdalcinl PetscFunctionReturn(0); 384471f87433Sdalcinl } 384571f87433Sdalcinl 384671f87433Sdalcinl #undef __FUNCT__ 3847fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 384871f87433Sdalcinl /*@ 3849fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 385071f87433Sdalcinl for computing relative tolerance for linear solvers within an 385171f87433Sdalcinl inexact Newton method. 385271f87433Sdalcinl 385371f87433Sdalcinl Not Collective 385471f87433Sdalcinl 385571f87433Sdalcinl Input Parameter: 385671f87433Sdalcinl . snes - SNES context 385771f87433Sdalcinl 385871f87433Sdalcinl Output Parameter: 385971f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 386071f87433Sdalcinl 386171f87433Sdalcinl Notes: 386271f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 386371f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 386471f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 386571f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 386671f87433Sdalcinl solver. 386771f87433Sdalcinl 386871f87433Sdalcinl Level: advanced 386971f87433Sdalcinl 387071f87433Sdalcinl Reference: 387171f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 387271f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 387371f87433Sdalcinl 387471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 387571f87433Sdalcinl 3876fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 387771f87433Sdalcinl @*/ 38787087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 387971f87433Sdalcinl { 388071f87433Sdalcinl PetscFunctionBegin; 38810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 388271f87433Sdalcinl PetscValidPointer(flag,2); 388371f87433Sdalcinl *flag = snes->ksp_ewconv; 388471f87433Sdalcinl PetscFunctionReturn(0); 388571f87433Sdalcinl } 388671f87433Sdalcinl 388771f87433Sdalcinl #undef __FUNCT__ 3888fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 388971f87433Sdalcinl /*@ 3890fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 389171f87433Sdalcinl convergence criteria for the linear solvers within an inexact 389271f87433Sdalcinl Newton method. 389371f87433Sdalcinl 38943f9fe445SBarry Smith Logically Collective on SNES 389571f87433Sdalcinl 389671f87433Sdalcinl Input Parameters: 389771f87433Sdalcinl + snes - SNES context 389871f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 389971f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 390071f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 390171f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 390271f87433Sdalcinl (0 <= gamma2 <= 1) 390371f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 390471f87433Sdalcinl . alpha2 - power for safeguard 390571f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 390671f87433Sdalcinl 390771f87433Sdalcinl Note: 390871f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 390971f87433Sdalcinl 391071f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 391171f87433Sdalcinl 391271f87433Sdalcinl Level: advanced 391371f87433Sdalcinl 391471f87433Sdalcinl Reference: 391571f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 391671f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 391771f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 391871f87433Sdalcinl 391971f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 392071f87433Sdalcinl 3921fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 392271f87433Sdalcinl @*/ 39237087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 392471f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 392571f87433Sdalcinl { 3926fa9f3622SBarry Smith SNESKSPEW *kctx; 392771f87433Sdalcinl PetscFunctionBegin; 39280700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3929fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3930e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 3931c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 3932c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 3933c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 3934c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 3935c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 3936c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 3937c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 393871f87433Sdalcinl 393971f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 394071f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 394171f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 394271f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 394371f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 394471f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 394571f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 394671f87433Sdalcinl 394771f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 3948e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 394971f87433Sdalcinl } 395071f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 3951e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 395271f87433Sdalcinl } 395371f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 3954e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 395571f87433Sdalcinl } 395671f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 3957e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 395871f87433Sdalcinl } 395971f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 3960e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 396171f87433Sdalcinl } 396271f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 3963e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 396471f87433Sdalcinl } 396571f87433Sdalcinl PetscFunctionReturn(0); 396671f87433Sdalcinl } 396771f87433Sdalcinl 396871f87433Sdalcinl #undef __FUNCT__ 3969fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 397071f87433Sdalcinl /*@ 3971fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 397271f87433Sdalcinl convergence criteria for the linear solvers within an inexact 397371f87433Sdalcinl Newton method. 397471f87433Sdalcinl 397571f87433Sdalcinl Not Collective 397671f87433Sdalcinl 397771f87433Sdalcinl Input Parameters: 397871f87433Sdalcinl snes - SNES context 397971f87433Sdalcinl 398071f87433Sdalcinl Output Parameters: 398171f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 398271f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 398371f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 398471f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 398571f87433Sdalcinl (0 <= gamma2 <= 1) 398671f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 398771f87433Sdalcinl . alpha2 - power for safeguard 398871f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 398971f87433Sdalcinl 399071f87433Sdalcinl Level: advanced 399171f87433Sdalcinl 399271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 399371f87433Sdalcinl 3994fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 399571f87433Sdalcinl @*/ 39967087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 399771f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 399871f87433Sdalcinl { 3999fa9f3622SBarry Smith SNESKSPEW *kctx; 400071f87433Sdalcinl PetscFunctionBegin; 40010700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4002fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4003e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 400471f87433Sdalcinl if(version) *version = kctx->version; 400571f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 400671f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 400771f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 400871f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 400971f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 401071f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 401171f87433Sdalcinl PetscFunctionReturn(0); 401271f87433Sdalcinl } 401371f87433Sdalcinl 401471f87433Sdalcinl #undef __FUNCT__ 4015fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 4016fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 401771f87433Sdalcinl { 401871f87433Sdalcinl PetscErrorCode ierr; 4019fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 402071f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 402171f87433Sdalcinl 402271f87433Sdalcinl PetscFunctionBegin; 4023e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 402471f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 402571f87433Sdalcinl rtol = kctx->rtol_0; 402671f87433Sdalcinl } else { 402771f87433Sdalcinl if (kctx->version == 1) { 402871f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 402971f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 403071f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 403171f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 403271f87433Sdalcinl } else if (kctx->version == 2) { 403371f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 403471f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 403571f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 403671f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 403771f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 403871f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 403971f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 404071f87433Sdalcinl stol = PetscMax(rtol,stol); 404171f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 404271f87433Sdalcinl /* safeguard: avoid oversolving */ 404371f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 404471f87433Sdalcinl stol = PetscMax(rtol,stol); 404571f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 4046e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 404771f87433Sdalcinl } 404871f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 404971f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 405071f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 405171f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 405271f87433Sdalcinl PetscFunctionReturn(0); 405371f87433Sdalcinl } 405471f87433Sdalcinl 405571f87433Sdalcinl #undef __FUNCT__ 4056fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 4057fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 405871f87433Sdalcinl { 405971f87433Sdalcinl PetscErrorCode ierr; 4060fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 406171f87433Sdalcinl PCSide pcside; 406271f87433Sdalcinl Vec lres; 406371f87433Sdalcinl 406471f87433Sdalcinl PetscFunctionBegin; 4065e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 406671f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 406771f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 406871f87433Sdalcinl if (kctx->version == 1) { 4069b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 407071f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 407171f87433Sdalcinl /* KSP residual is true linear residual */ 407271f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 407371f87433Sdalcinl } else { 407471f87433Sdalcinl /* KSP residual is preconditioned residual */ 407571f87433Sdalcinl /* compute true linear residual norm */ 407671f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 407771f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 407871f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 407971f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 40806bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 408171f87433Sdalcinl } 408271f87433Sdalcinl } 408371f87433Sdalcinl PetscFunctionReturn(0); 408471f87433Sdalcinl } 408571f87433Sdalcinl 408671f87433Sdalcinl #undef __FUNCT__ 408771f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 408871f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 408971f87433Sdalcinl { 409071f87433Sdalcinl PetscErrorCode ierr; 409171f87433Sdalcinl 409271f87433Sdalcinl PetscFunctionBegin; 4093fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 409471f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 4095fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 409671f87433Sdalcinl PetscFunctionReturn(0); 409771f87433Sdalcinl } 40986c699258SBarry Smith 40996c699258SBarry Smith #undef __FUNCT__ 41006c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 41016c699258SBarry Smith /*@ 41026c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 41036c699258SBarry Smith 41043f9fe445SBarry Smith Logically Collective on SNES 41056c699258SBarry Smith 41066c699258SBarry Smith Input Parameters: 41076c699258SBarry Smith + snes - the preconditioner context 41086c699258SBarry Smith - dm - the dm 41096c699258SBarry Smith 41106c699258SBarry Smith Level: intermediate 41116c699258SBarry Smith 41126c699258SBarry Smith 41136c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 41146c699258SBarry Smith @*/ 41157087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 41166c699258SBarry Smith { 41176c699258SBarry Smith PetscErrorCode ierr; 4118345fed2cSBarry Smith KSP ksp; 41196cab3a1bSJed Brown SNESDM sdm; 41206c699258SBarry Smith 41216c699258SBarry Smith PetscFunctionBegin; 41220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4123d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 41246cab3a1bSJed Brown if (snes->dm) { /* Move the SNESDM context over to the new DM unless the new DM already has one */ 41256cab3a1bSJed Brown PetscContainer oldcontainer,container; 41266cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 41276cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr); 41286cab3a1bSJed Brown if (oldcontainer && !container) { 41296cab3a1bSJed Brown ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr); 41306cab3a1bSJed Brown ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr); 41316cab3a1bSJed Brown if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */ 41326cab3a1bSJed Brown sdm->originaldm = dm; 41336cab3a1bSJed Brown } 41346cab3a1bSJed Brown } 41356bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 41366cab3a1bSJed Brown } 41376c699258SBarry Smith snes->dm = dm; 4138345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4139345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4140f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 41412c155ee1SBarry Smith if (snes->pc) { 41422c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 41432c155ee1SBarry Smith } 41446c699258SBarry Smith PetscFunctionReturn(0); 41456c699258SBarry Smith } 41466c699258SBarry Smith 41476c699258SBarry Smith #undef __FUNCT__ 41486c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 41496c699258SBarry Smith /*@ 41506c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 41516c699258SBarry Smith 41523f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 41536c699258SBarry Smith 41546c699258SBarry Smith Input Parameter: 41556c699258SBarry Smith . snes - the preconditioner context 41566c699258SBarry Smith 41576c699258SBarry Smith Output Parameter: 41586c699258SBarry Smith . dm - the dm 41596c699258SBarry Smith 41606c699258SBarry Smith Level: intermediate 41616c699258SBarry Smith 41626c699258SBarry Smith 41636c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 41646c699258SBarry Smith @*/ 41657087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 41666c699258SBarry Smith { 41676cab3a1bSJed Brown PetscErrorCode ierr; 41686cab3a1bSJed Brown 41696c699258SBarry Smith PetscFunctionBegin; 41700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 41716cab3a1bSJed Brown if (!snes->dm) { 41726cab3a1bSJed Brown ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr); 41736cab3a1bSJed Brown } 41746c699258SBarry Smith *dm = snes->dm; 41756c699258SBarry Smith PetscFunctionReturn(0); 41766c699258SBarry Smith } 41770807856dSBarry Smith 417831823bd8SMatthew G Knepley #undef __FUNCT__ 417931823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 418031823bd8SMatthew G Knepley /*@ 4181fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 418231823bd8SMatthew G Knepley 418331823bd8SMatthew G Knepley Collective on SNES 418431823bd8SMatthew G Knepley 418531823bd8SMatthew G Knepley Input Parameters: 418631823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 418731823bd8SMatthew G Knepley - pc - the preconditioner object 418831823bd8SMatthew G Knepley 418931823bd8SMatthew G Knepley Notes: 419031823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 419131823bd8SMatthew G Knepley to configure it using the API). 419231823bd8SMatthew G Knepley 419331823bd8SMatthew G Knepley Level: developer 419431823bd8SMatthew G Knepley 419531823bd8SMatthew G Knepley .keywords: SNES, set, precondition 419631823bd8SMatthew G Knepley .seealso: SNESGetPC() 419731823bd8SMatthew G Knepley @*/ 419831823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 419931823bd8SMatthew G Knepley { 420031823bd8SMatthew G Knepley PetscErrorCode ierr; 420131823bd8SMatthew G Knepley 420231823bd8SMatthew G Knepley PetscFunctionBegin; 420331823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 420431823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 420531823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 420631823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4207bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 420831823bd8SMatthew G Knepley snes->pc = pc; 420931823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 421031823bd8SMatthew G Knepley PetscFunctionReturn(0); 421131823bd8SMatthew G Knepley } 421231823bd8SMatthew G Knepley 421331823bd8SMatthew G Knepley #undef __FUNCT__ 421431823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 421531823bd8SMatthew G Knepley /*@ 4216fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 421731823bd8SMatthew G Knepley 421831823bd8SMatthew G Knepley Not Collective 421931823bd8SMatthew G Knepley 422031823bd8SMatthew G Knepley Input Parameter: 422131823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 422231823bd8SMatthew G Knepley 422331823bd8SMatthew G Knepley Output Parameter: 422431823bd8SMatthew G Knepley . pc - preconditioner context 422531823bd8SMatthew G Knepley 422631823bd8SMatthew G Knepley Level: developer 422731823bd8SMatthew G Knepley 422831823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 422931823bd8SMatthew G Knepley .seealso: SNESSetPC() 423031823bd8SMatthew G Knepley @*/ 423131823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 423231823bd8SMatthew G Knepley { 423331823bd8SMatthew G Knepley PetscErrorCode ierr; 423431823bd8SMatthew G Knepley 423531823bd8SMatthew G Knepley PetscFunctionBegin; 423631823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 423731823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 423831823bd8SMatthew G Knepley if (!snes->pc) { 423931823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr); 42404a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr); 424131823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 424231823bd8SMatthew G Knepley } 424331823bd8SMatthew G Knepley *pc = snes->pc; 424431823bd8SMatthew G Knepley PetscFunctionReturn(0); 424531823bd8SMatthew G Knepley } 424631823bd8SMatthew G Knepley 42479e764e56SPeter Brune #undef __FUNCT__ 4248f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch" 42499e764e56SPeter Brune /*@ 4250f1c6b773SPeter Brune SNESSetSNESLineSearch - Sets the linesearch. 42519e764e56SPeter Brune 42529e764e56SPeter Brune Collective on SNES 42539e764e56SPeter Brune 42549e764e56SPeter Brune Input Parameters: 42559e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 42569e764e56SPeter Brune - linesearch - the linesearch object 42579e764e56SPeter Brune 42589e764e56SPeter Brune Notes: 4259f1c6b773SPeter Brune Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example, 42609e764e56SPeter Brune to configure it using the API). 42619e764e56SPeter Brune 42629e764e56SPeter Brune Level: developer 42639e764e56SPeter Brune 42649e764e56SPeter Brune .keywords: SNES, set, linesearch 4265f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch() 42669e764e56SPeter Brune @*/ 4267f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch) 42689e764e56SPeter Brune { 42699e764e56SPeter Brune PetscErrorCode ierr; 42709e764e56SPeter Brune 42719e764e56SPeter Brune PetscFunctionBegin; 42729e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4273f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 42749e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 42759e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 4276f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 42779e764e56SPeter Brune snes->linesearch = linesearch; 42789e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 42799e764e56SPeter Brune PetscFunctionReturn(0); 42809e764e56SPeter Brune } 42819e764e56SPeter Brune 42829e764e56SPeter Brune #undef __FUNCT__ 4283f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch" 4284ea5d4fccSPeter Brune /*@C 4285f1c6b773SPeter Brune SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch(). 42869e764e56SPeter Brune 42879e764e56SPeter Brune Not Collective 42889e764e56SPeter Brune 42899e764e56SPeter Brune Input Parameter: 42909e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 42919e764e56SPeter Brune 42929e764e56SPeter Brune Output Parameter: 42939e764e56SPeter Brune . linesearch - linesearch context 42949e764e56SPeter Brune 42959e764e56SPeter Brune Level: developer 42969e764e56SPeter Brune 42979e764e56SPeter Brune .keywords: SNES, get, linesearch 4298f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch() 42999e764e56SPeter Brune @*/ 4300f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch) 43019e764e56SPeter Brune { 43029e764e56SPeter Brune PetscErrorCode ierr; 43039e764e56SPeter Brune const char *optionsprefix; 43049e764e56SPeter Brune 43059e764e56SPeter Brune PetscFunctionBegin; 43069e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 43079e764e56SPeter Brune PetscValidPointer(linesearch, 2); 43089e764e56SPeter Brune if (!snes->linesearch) { 43099e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 4310f1c6b773SPeter Brune ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr); 4311f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 4312b1dca40bSPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 43139e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 43149e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 43159e764e56SPeter Brune } 43169e764e56SPeter Brune *linesearch = snes->linesearch; 43179e764e56SPeter Brune PetscFunctionReturn(0); 43189e764e56SPeter Brune } 43199e764e56SPeter Brune 432069b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4321c6db04a5SJed Brown #include <mex.h> 432269b4f73cSBarry Smith 43238f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 43248f6e6473SBarry Smith 43250807856dSBarry Smith #undef __FUNCT__ 43260807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 43270807856dSBarry Smith /* 43280807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 43290807856dSBarry Smith SNESSetFunctionMatlab(). 43300807856dSBarry Smith 43310807856dSBarry Smith Collective on SNES 43320807856dSBarry Smith 43330807856dSBarry Smith Input Parameters: 43340807856dSBarry Smith + snes - the SNES context 43350807856dSBarry Smith - x - input vector 43360807856dSBarry Smith 43370807856dSBarry Smith Output Parameter: 43380807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 43390807856dSBarry Smith 43400807856dSBarry Smith Notes: 43410807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 43420807856dSBarry Smith implementations, so most users would not generally call this routine 43430807856dSBarry Smith themselves. 43440807856dSBarry Smith 43450807856dSBarry Smith Level: developer 43460807856dSBarry Smith 43470807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 43480807856dSBarry Smith 43490807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 435061b2408cSBarry Smith */ 43517087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 43520807856dSBarry Smith { 4353e650e774SBarry Smith PetscErrorCode ierr; 43548f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 43558f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 43568f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 435791621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 4358e650e774SBarry Smith 43590807856dSBarry Smith PetscFunctionBegin; 43600807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 43610807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 43620807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 43630807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 43640807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 43650807856dSBarry Smith 43660807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 4367e650e774SBarry Smith 436891621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4369e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4370e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 437191621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 437291621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 437391621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 43748f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 43758f6e6473SBarry Smith prhs[4] = sctx->ctx; 4376b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 4377e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4378e650e774SBarry Smith mxDestroyArray(prhs[0]); 4379e650e774SBarry Smith mxDestroyArray(prhs[1]); 4380e650e774SBarry Smith mxDestroyArray(prhs[2]); 43818f6e6473SBarry Smith mxDestroyArray(prhs[3]); 4382e650e774SBarry Smith mxDestroyArray(plhs[0]); 43830807856dSBarry Smith PetscFunctionReturn(0); 43840807856dSBarry Smith } 43850807856dSBarry Smith 43860807856dSBarry Smith 43870807856dSBarry Smith #undef __FUNCT__ 43880807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 438961b2408cSBarry Smith /* 43900807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 43910807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4392e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 43930807856dSBarry Smith 43940807856dSBarry Smith Logically Collective on SNES 43950807856dSBarry Smith 43960807856dSBarry Smith Input Parameters: 43970807856dSBarry Smith + snes - the SNES context 43980807856dSBarry Smith . r - vector to store function value 43990807856dSBarry Smith - func - function evaluation routine 44000807856dSBarry Smith 44010807856dSBarry Smith Calling sequence of func: 440261b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 44030807856dSBarry Smith 44040807856dSBarry Smith 44050807856dSBarry Smith Notes: 44060807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 44070807856dSBarry Smith $ f'(x) x = -f(x), 44080807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 44090807856dSBarry Smith 44100807856dSBarry Smith Level: beginner 44110807856dSBarry Smith 44120807856dSBarry Smith .keywords: SNES, nonlinear, set, function 44130807856dSBarry Smith 44140807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 441561b2408cSBarry Smith */ 44167087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 44170807856dSBarry Smith { 44180807856dSBarry Smith PetscErrorCode ierr; 44198f6e6473SBarry Smith SNESMatlabContext *sctx; 44200807856dSBarry Smith 44210807856dSBarry Smith PetscFunctionBegin; 44228f6e6473SBarry Smith /* currently sctx is memory bleed */ 44238f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 44248f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 44258f6e6473SBarry Smith /* 44268f6e6473SBarry Smith This should work, but it doesn't 44278f6e6473SBarry Smith sctx->ctx = ctx; 44288f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 44298f6e6473SBarry Smith */ 44308f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 44318f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 44320807856dSBarry Smith PetscFunctionReturn(0); 44330807856dSBarry Smith } 443469b4f73cSBarry Smith 443561b2408cSBarry Smith #undef __FUNCT__ 443661b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 443761b2408cSBarry Smith /* 443861b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 443961b2408cSBarry Smith SNESSetJacobianMatlab(). 444061b2408cSBarry Smith 444161b2408cSBarry Smith Collective on SNES 444261b2408cSBarry Smith 444361b2408cSBarry Smith Input Parameters: 444461b2408cSBarry Smith + snes - the SNES context 444561b2408cSBarry Smith . x - input vector 444661b2408cSBarry Smith . A, B - the matrices 444761b2408cSBarry Smith - ctx - user context 444861b2408cSBarry Smith 444961b2408cSBarry Smith Output Parameter: 445061b2408cSBarry Smith . flag - structure of the matrix 445161b2408cSBarry Smith 445261b2408cSBarry Smith Level: developer 445361b2408cSBarry Smith 445461b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 445561b2408cSBarry Smith 445661b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 445761b2408cSBarry Smith @*/ 44587087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 445961b2408cSBarry Smith { 446061b2408cSBarry Smith PetscErrorCode ierr; 446161b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 446261b2408cSBarry Smith int nlhs = 2,nrhs = 6; 446361b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 446461b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 446561b2408cSBarry Smith 446661b2408cSBarry Smith PetscFunctionBegin; 446761b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 446861b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 446961b2408cSBarry Smith 447061b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 447161b2408cSBarry Smith 447261b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 447361b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 447461b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 447561b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 447661b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 447761b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 447861b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 447961b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 448061b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 448161b2408cSBarry Smith prhs[5] = sctx->ctx; 4482b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 448361b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 448461b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 448561b2408cSBarry Smith mxDestroyArray(prhs[0]); 448661b2408cSBarry Smith mxDestroyArray(prhs[1]); 448761b2408cSBarry Smith mxDestroyArray(prhs[2]); 448861b2408cSBarry Smith mxDestroyArray(prhs[3]); 448961b2408cSBarry Smith mxDestroyArray(prhs[4]); 449061b2408cSBarry Smith mxDestroyArray(plhs[0]); 449161b2408cSBarry Smith mxDestroyArray(plhs[1]); 449261b2408cSBarry Smith PetscFunctionReturn(0); 449361b2408cSBarry Smith } 449461b2408cSBarry Smith 449561b2408cSBarry Smith 449661b2408cSBarry Smith #undef __FUNCT__ 449761b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 449861b2408cSBarry Smith /* 449961b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 450061b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4501e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 450261b2408cSBarry Smith 450361b2408cSBarry Smith Logically Collective on SNES 450461b2408cSBarry Smith 450561b2408cSBarry Smith Input Parameters: 450661b2408cSBarry Smith + snes - the SNES context 450761b2408cSBarry Smith . A,B - Jacobian matrices 450861b2408cSBarry Smith . func - function evaluation routine 450961b2408cSBarry Smith - ctx - user context 451061b2408cSBarry Smith 451161b2408cSBarry Smith Calling sequence of func: 451261b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 451361b2408cSBarry Smith 451461b2408cSBarry Smith 451561b2408cSBarry Smith Level: developer 451661b2408cSBarry Smith 451761b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 451861b2408cSBarry Smith 451961b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 452061b2408cSBarry Smith */ 45217087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 452261b2408cSBarry Smith { 452361b2408cSBarry Smith PetscErrorCode ierr; 452461b2408cSBarry Smith SNESMatlabContext *sctx; 452561b2408cSBarry Smith 452661b2408cSBarry Smith PetscFunctionBegin; 452761b2408cSBarry Smith /* currently sctx is memory bleed */ 452861b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 452961b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 453061b2408cSBarry Smith /* 453161b2408cSBarry Smith This should work, but it doesn't 453261b2408cSBarry Smith sctx->ctx = ctx; 453361b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 453461b2408cSBarry Smith */ 453561b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 453661b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 453761b2408cSBarry Smith PetscFunctionReturn(0); 453861b2408cSBarry Smith } 453969b4f73cSBarry Smith 4540f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4541f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4542f9eb7ae2SShri Abhyankar /* 4543f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4544f9eb7ae2SShri Abhyankar 4545f9eb7ae2SShri Abhyankar Collective on SNES 4546f9eb7ae2SShri Abhyankar 4547f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4548f9eb7ae2SShri Abhyankar @*/ 45497087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4550f9eb7ae2SShri Abhyankar { 4551f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 455248f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4553f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4554f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4555f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4556f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4557f9eb7ae2SShri Abhyankar 4558f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4559f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4560f9eb7ae2SShri Abhyankar 4561f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4562f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4563f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4564f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4565f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4566f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4567f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4568f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4569f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4570f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4571f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4572f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4573f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4574f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4575f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4576f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4577f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4578f9eb7ae2SShri Abhyankar } 4579f9eb7ae2SShri Abhyankar 4580f9eb7ae2SShri Abhyankar 4581f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4582f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4583f9eb7ae2SShri Abhyankar /* 4584e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4585f9eb7ae2SShri Abhyankar 4586f9eb7ae2SShri Abhyankar Level: developer 4587f9eb7ae2SShri Abhyankar 4588f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4589f9eb7ae2SShri Abhyankar 4590f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4591f9eb7ae2SShri Abhyankar */ 45927087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4593f9eb7ae2SShri Abhyankar { 4594f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4595f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4596f9eb7ae2SShri Abhyankar 4597f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4598f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4599f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4600f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4601f9eb7ae2SShri Abhyankar /* 4602f9eb7ae2SShri Abhyankar This should work, but it doesn't 4603f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4604f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4605f9eb7ae2SShri Abhyankar */ 4606f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4607f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4608f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4609f9eb7ae2SShri Abhyankar } 4610f9eb7ae2SShri Abhyankar 461169b4f73cSBarry Smith #endif 4612