19b94acceSBarry Smith 2c6db04a5SJed Brown #include <private/snesimpl.h> /*I "petscsnes.h" I*/ 36cab3a1bSJed Brown #include <petscdmshell.h> /*I "petscdmshell.h" I*/ 49b94acceSBarry Smith 5ace3abfcSBarry Smith PetscBool SNESRegisterAllCalled = PETSC_FALSE; 68ba1e511SMatthew Knepley PetscFList SNESList = PETSC_NULL; 78ba1e511SMatthew Knepley 88ba1e511SMatthew Knepley /* Logging support */ 97087cfbeSBarry Smith PetscClassId SNES_CLASSID; 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", 205*c60f73f4SPeter 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__ 341caa4e7f2SJed Brown #define __FUNCT__ "KSPComputeOperators_SNES" 342caa4e7f2SJed Brown static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,MatStructure *mstruct,void *ctx) 343caa4e7f2SJed Brown { 344caa4e7f2SJed Brown SNES snes = (SNES)ctx; 345caa4e7f2SJed Brown PetscErrorCode ierr; 346caa4e7f2SJed Brown Mat Asave = A,Bsave = B; 347caa4e7f2SJed Brown 348caa4e7f2SJed Brown PetscFunctionBegin; 349caa4e7f2SJed Brown ierr = SNESComputeJacobian(snes,snes->vec_sol,&A,&B,mstruct);CHKERRQ(ierr); 350caa4e7f2SJed Brown if (A != Asave || B != Bsave) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"No support for changing matrices at this time"); 351caa4e7f2SJed Brown PetscFunctionReturn(0); 352caa4e7f2SJed Brown } 353caa4e7f2SJed Brown 354caa4e7f2SJed Brown #undef __FUNCT__ 3556cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices" 3566cab3a1bSJed Brown /*@ 3576cab3a1bSJed Brown SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX() 3586cab3a1bSJed Brown 3596cab3a1bSJed Brown Collective 3606cab3a1bSJed Brown 3616cab3a1bSJed Brown Input Arguments: 3626cab3a1bSJed Brown . snes - snes to configure 3636cab3a1bSJed Brown 3646cab3a1bSJed Brown Level: developer 3656cab3a1bSJed Brown 3666cab3a1bSJed Brown .seealso: SNESSetUp() 3676cab3a1bSJed Brown @*/ 3686cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes) 3696cab3a1bSJed Brown { 3706cab3a1bSJed Brown PetscErrorCode ierr; 3716cab3a1bSJed Brown DM dm; 3726cab3a1bSJed Brown SNESDM sdm; 3736cab3a1bSJed Brown 3746cab3a1bSJed Brown PetscFunctionBegin; 3756cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3766cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 377caa4e7f2SJed Brown if (!sdm->computejacobian) { 3786cab3a1bSJed Brown Mat J,B; 3796cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 3806cab3a1bSJed Brown if (snes->mf_operator) { 3816cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 3826cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 3836cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 3846cab3a1bSJed Brown } else { 3856cab3a1bSJed Brown J = B; 3866cab3a1bSJed Brown ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr); 3876cab3a1bSJed Brown } 3886cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr); 3896cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 3906cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 3916cab3a1bSJed Brown } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) { 3926cab3a1bSJed Brown Mat J; 3936cab3a1bSJed Brown void *functx; 3946cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 3956cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 3966cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 3976cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 3986cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr); 3996cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 400caa4e7f2SJed Brown } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 4016cab3a1bSJed Brown Mat J,B; 4026cab3a1bSJed Brown void *functx; 4036cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4046cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4056cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4066cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 4076cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 4086cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,functx);CHKERRQ(ierr); 4096cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 4106cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 411caa4e7f2SJed Brown } else if (!snes->jacobian_pre) { 4126cab3a1bSJed Brown Mat J,B; 4136cab3a1bSJed Brown J = snes->jacobian; 4146cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 4156cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 4166cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 4176cab3a1bSJed Brown } 418caa4e7f2SJed Brown { 419caa4e7f2SJed Brown PetscBool flg = PETSC_FALSE; 420caa4e7f2SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_kspcompute",&flg,PETSC_NULL);CHKERRQ(ierr); 421caa4e7f2SJed Brown if (flg) { /* Plan to transition to this model */ 422caa4e7f2SJed Brown KSP ksp; 423caa4e7f2SJed Brown ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 424caa4e7f2SJed Brown ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr); 425caa4e7f2SJed Brown } 426caa4e7f2SJed Brown } 4276cab3a1bSJed Brown PetscFunctionReturn(0); 4286cab3a1bSJed Brown } 4296cab3a1bSJed Brown 4306cab3a1bSJed Brown #undef __FUNCT__ 4314a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions" 4329b94acceSBarry Smith /*@ 43394b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 4349b94acceSBarry Smith 435c7afd0dbSLois Curfman McInnes Collective on SNES 436c7afd0dbSLois Curfman McInnes 4379b94acceSBarry Smith Input Parameter: 4389b94acceSBarry Smith . snes - the SNES context 4399b94acceSBarry Smith 44036851e7fSLois Curfman McInnes Options Database Keys: 441ea630c6eSPeter Brune + -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas 44282738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 44382738288SBarry Smith of the change in the solution between steps 44470441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 445b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 446b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 447b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 4484839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 449ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 450a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 451e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 452b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 4532492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 45482738288SBarry Smith solver; hence iterations will continue until max_it 4551fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 45682738288SBarry Smith of convergence test 457e8105e01SRichard Katz . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 458e8105e01SRichard Katz filename given prints to stdout 459a6570f20SBarry Smith . -snes_monitor_solution - plots solution at each iteration 460a6570f20SBarry Smith . -snes_monitor_residual - plots residual (not its norm) at each iteration 461a6570f20SBarry Smith . -snes_monitor_solution_update - plots update to solution at each iteration 462a6570f20SBarry Smith . -snes_monitor_draw - plots residual norm at each iteration 463e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 4645968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 465fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 46682738288SBarry Smith 46782738288SBarry Smith Options Database for Eisenstat-Walker method: 468fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 4694b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 47036851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 47136851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 47236851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 47336851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 47436851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 47536851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 47682738288SBarry Smith 47711ca99fdSLois Curfman McInnes Notes: 47811ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 4790598bfebSBarry Smith the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>. 48083e2fdc7SBarry Smith 48136851e7fSLois Curfman McInnes Level: beginner 48236851e7fSLois Curfman McInnes 4839b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 4849b94acceSBarry Smith 48569ed319cSSatish Balay .seealso: SNESSetOptionsPrefix() 4869b94acceSBarry Smith @*/ 4877087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 4889b94acceSBarry Smith { 489872b6db9SPeter Brune PetscBool flg,mf,mf_operator,pcset; 490efd51863SBarry Smith PetscInt i,indx,lag,mf_version,grids; 491aa3661deSLisandro Dalcin MatStructure matflag; 49285385478SLisandro Dalcin const char *deft = SNESLS; 49385385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 49485385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 495e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 49651e86f29SPeter Brune const char *optionsprefix; 497649052a6SBarry Smith PetscViewer monviewer; 49885385478SLisandro Dalcin PetscErrorCode ierr; 4999b94acceSBarry Smith 5003a40ed3dSBarry Smith PetscFunctionBegin; 5010700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 502ca161407SBarry Smith 503186905e3SBarry Smith if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 5043194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 5057adad957SLisandro Dalcin if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; } 506b0a32e0cSBarry Smith ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 507d64ed03dSBarry Smith if (flg) { 508186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 5097adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 510186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 511d64ed03dSBarry Smith } 51290d69ab7SBarry Smith /* not used here, but called so will go into help messaage */ 513909c8a9fSBarry Smith ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 51493c39befSBarry Smith 515*c60f73f4SPeter Brune ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr); 51657034d6fSHong Zhang ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 517186905e3SBarry Smith 51857034d6fSHong Zhang ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 519b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 520b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 52150ffb88aSMatthew Knepley ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 522ddf469c8SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr); 523acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr); 52485385478SLisandro Dalcin 525a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 526a8054027SBarry Smith if (flg) { 527a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 528a8054027SBarry Smith } 529e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 530e35cf81dSBarry Smith if (flg) { 531e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 532e35cf81dSBarry Smith } 533efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 534efd51863SBarry Smith if (flg) { 535efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 536efd51863SBarry Smith } 537a8054027SBarry Smith 53885385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 53985385478SLisandro Dalcin if (flg) { 54085385478SLisandro Dalcin switch (indx) { 5417f7931b9SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 5427f7931b9SBarry Smith case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 54385385478SLisandro Dalcin } 54485385478SLisandro Dalcin } 54585385478SLisandro Dalcin 546acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr); 547186905e3SBarry Smith 54885385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 54985385478SLisandro Dalcin 550acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 551186905e3SBarry Smith 552fa9f3622SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 553fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 554fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 555fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 556fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 557fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 558fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 559186905e3SBarry Smith 56090d69ab7SBarry Smith flg = PETSC_FALSE; 561acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 562a6570f20SBarry Smith if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 563eabae89aSBarry Smith 564a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 565e8105e01SRichard Katz if (flg) { 566649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 567649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 568e8105e01SRichard Katz } 569eabae89aSBarry Smith 570b271bb04SBarry Smith ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 571b271bb04SBarry Smith if (flg) { 572b271bb04SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 573b271bb04SBarry Smith } 574b271bb04SBarry Smith 575a6570f20SBarry Smith ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 576eabae89aSBarry Smith if (flg) { 577649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 578f1bef1bcSMatthew Knepley ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 579e8105e01SRichard Katz } 580eabae89aSBarry Smith 581a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 582eabae89aSBarry Smith if (flg) { 583649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 584649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 585eabae89aSBarry Smith } 586eabae89aSBarry Smith 5875180491cSLisandro Dalcin ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 5885180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 5895180491cSLisandro Dalcin 59090d69ab7SBarry Smith flg = PETSC_FALSE; 591acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 592a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 59390d69ab7SBarry Smith flg = PETSC_FALSE; 594acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 595a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 59690d69ab7SBarry Smith flg = PETSC_FALSE; 597acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 598a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 59990d69ab7SBarry Smith flg = PETSC_FALSE; 600acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 601a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 60290d69ab7SBarry Smith flg = PETSC_FALSE; 603acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 604b271bb04SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 605e24b481bSBarry Smith 60690d69ab7SBarry Smith flg = PETSC_FALSE; 607acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 6084b27c08aSLois Curfman McInnes if (flg) { 6096cab3a1bSJed Brown void *functx; 6106cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 6116cab3a1bSJed Brown ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr); 612ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 6139b94acceSBarry Smith } 614639f9d9dSBarry Smith 615aa3661deSLisandro Dalcin mf = mf_operator = PETSC_FALSE; 616aa3661deSLisandro Dalcin flg = PETSC_FALSE; 617acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr); 618a8248277SBarry Smith if (flg && mf_operator) { 619a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 620a8248277SBarry Smith mf = PETSC_TRUE; 621a8248277SBarry Smith } 622aa3661deSLisandro Dalcin flg = PETSC_FALSE; 623acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr); 624aa3661deSLisandro Dalcin if (!flg && mf_operator) mf = PETSC_TRUE; 625aa3661deSLisandro Dalcin mf_version = 1; 626aa3661deSLisandro Dalcin ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr); 627aa3661deSLisandro Dalcin 628d28543b3SPeter Brune 62989b92e6fSPeter Brune /* GS Options */ 63089b92e6fSPeter Brune ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr); 63189b92e6fSPeter Brune 63276b2cf59SMatthew Knepley for(i = 0; i < numberofsetfromoptions; i++) { 63376b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 63476b2cf59SMatthew Knepley } 63576b2cf59SMatthew Knepley 636e7788613SBarry Smith if (snes->ops->setfromoptions) { 637e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 638639f9d9dSBarry Smith } 6395d973c19SBarry Smith 6405d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 6415d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 642b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 6434bbc92c1SBarry Smith 644aa3661deSLisandro Dalcin if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 6451cee3971SBarry Smith 6461cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 647aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 648aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 64985385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 65093993e2dSLois Curfman McInnes 6519e764e56SPeter Brune if (!snes->linesearch) { 652f1c6b773SPeter Brune ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 6539e764e56SPeter Brune } 654f1c6b773SPeter Brune ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr); 6559e764e56SPeter Brune 65651e86f29SPeter Brune /* if someone has set the SNES PC type, create it. */ 65751e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 65851e86f29SPeter Brune ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 65951e86f29SPeter Brune if (pcset && (!snes->pc)) { 66051e86f29SPeter Brune ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr); 66151e86f29SPeter Brune } 6624a0c5b0cSMatthew G Knepley if (snes->pc) { 663fde0ff24SPeter Brune ierr = SNESSetOptionsPrefix(snes->pc, optionsprefix);CHKERRQ(ierr); 664fde0ff24SPeter Brune ierr = SNESAppendOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr); 6654a0c5b0cSMatthew G Knepley ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 6664a0c5b0cSMatthew G Knepley ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 6674a0c5b0cSMatthew G Knepley } 6683a40ed3dSBarry Smith PetscFunctionReturn(0); 6699b94acceSBarry Smith } 6709b94acceSBarry Smith 671d25893d9SBarry Smith #undef __FUNCT__ 672d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 673d25893d9SBarry Smith /*@ 674d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 675d25893d9SBarry Smith the nonlinear solvers. 676d25893d9SBarry Smith 677d25893d9SBarry Smith Logically Collective on SNES 678d25893d9SBarry Smith 679d25893d9SBarry Smith Input Parameters: 680d25893d9SBarry Smith + snes - the SNES context 681d25893d9SBarry Smith . compute - function to compute the context 682d25893d9SBarry Smith - destroy - function to destroy the context 683d25893d9SBarry Smith 684d25893d9SBarry Smith Level: intermediate 685d25893d9SBarry Smith 686d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 687d25893d9SBarry Smith 688d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 689d25893d9SBarry Smith @*/ 690d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 691d25893d9SBarry Smith { 692d25893d9SBarry Smith PetscFunctionBegin; 693d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 694d25893d9SBarry Smith snes->ops->usercompute = compute; 695d25893d9SBarry Smith snes->ops->userdestroy = destroy; 696d25893d9SBarry Smith PetscFunctionReturn(0); 697d25893d9SBarry Smith } 698a847f771SSatish Balay 6994a2ae208SSatish Balay #undef __FUNCT__ 7004a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 701b07ff414SBarry Smith /*@ 7029b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 7039b94acceSBarry Smith the nonlinear solvers. 7049b94acceSBarry Smith 7053f9fe445SBarry Smith Logically Collective on SNES 706fee21e36SBarry Smith 707c7afd0dbSLois Curfman McInnes Input Parameters: 708c7afd0dbSLois Curfman McInnes + snes - the SNES context 709c7afd0dbSLois Curfman McInnes - usrP - optional user context 710c7afd0dbSLois Curfman McInnes 71136851e7fSLois Curfman McInnes Level: intermediate 71236851e7fSLois Curfman McInnes 7139b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 7149b94acceSBarry Smith 715d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext() 7169b94acceSBarry Smith @*/ 7177087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 7189b94acceSBarry Smith { 7191b2093e4SBarry Smith PetscErrorCode ierr; 720b07ff414SBarry Smith KSP ksp; 7211b2093e4SBarry Smith 7223a40ed3dSBarry Smith PetscFunctionBegin; 7230700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 724b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 725b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 7269b94acceSBarry Smith snes->user = usrP; 7273a40ed3dSBarry Smith PetscFunctionReturn(0); 7289b94acceSBarry Smith } 72974679c65SBarry Smith 7304a2ae208SSatish Balay #undef __FUNCT__ 7314a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 732b07ff414SBarry Smith /*@ 7339b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 7349b94acceSBarry Smith nonlinear solvers. 7359b94acceSBarry Smith 736c7afd0dbSLois Curfman McInnes Not Collective 737c7afd0dbSLois Curfman McInnes 7389b94acceSBarry Smith Input Parameter: 7399b94acceSBarry Smith . snes - SNES context 7409b94acceSBarry Smith 7419b94acceSBarry Smith Output Parameter: 7429b94acceSBarry Smith . usrP - user context 7439b94acceSBarry Smith 74436851e7fSLois Curfman McInnes Level: intermediate 74536851e7fSLois Curfman McInnes 7469b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 7479b94acceSBarry Smith 7489b94acceSBarry Smith .seealso: SNESSetApplicationContext() 7499b94acceSBarry Smith @*/ 750e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 7519b94acceSBarry Smith { 7523a40ed3dSBarry Smith PetscFunctionBegin; 7530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 754e71120c6SJed Brown *(void**)usrP = snes->user; 7553a40ed3dSBarry Smith PetscFunctionReturn(0); 7569b94acceSBarry Smith } 75774679c65SBarry Smith 7584a2ae208SSatish Balay #undef __FUNCT__ 7594a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 7609b94acceSBarry Smith /*@ 761c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 762c8228a4eSBarry Smith at this time. 7639b94acceSBarry Smith 764c7afd0dbSLois Curfman McInnes Not Collective 765c7afd0dbSLois Curfman McInnes 7669b94acceSBarry Smith Input Parameter: 7679b94acceSBarry Smith . snes - SNES context 7689b94acceSBarry Smith 7699b94acceSBarry Smith Output Parameter: 7709b94acceSBarry Smith . iter - iteration number 7719b94acceSBarry Smith 772c8228a4eSBarry Smith Notes: 773c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 774c8228a4eSBarry Smith 775c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 77608405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 77708405cd6SLois Curfman McInnes .vb 77808405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 77908405cd6SLois Curfman McInnes if (!(it % 2)) { 78008405cd6SLois Curfman McInnes [compute Jacobian here] 78108405cd6SLois Curfman McInnes } 78208405cd6SLois Curfman McInnes .ve 783c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 78408405cd6SLois Curfman McInnes recomputed every second SNES iteration. 785c8228a4eSBarry Smith 78636851e7fSLois Curfman McInnes Level: intermediate 78736851e7fSLois Curfman McInnes 7882b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 7892b668275SBarry Smith 790b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 7919b94acceSBarry Smith @*/ 7927087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 7939b94acceSBarry Smith { 7943a40ed3dSBarry Smith PetscFunctionBegin; 7950700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7964482741eSBarry Smith PetscValidIntPointer(iter,2); 7979b94acceSBarry Smith *iter = snes->iter; 7983a40ed3dSBarry Smith PetscFunctionReturn(0); 7999b94acceSBarry Smith } 80074679c65SBarry Smith 8014a2ae208SSatish Balay #undef __FUNCT__ 802360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber" 803360c497dSPeter Brune /*@ 804360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 805360c497dSPeter Brune 806360c497dSPeter Brune Not Collective 807360c497dSPeter Brune 808360c497dSPeter Brune Input Parameter: 809360c497dSPeter Brune . snes - SNES context 810360c497dSPeter Brune . iter - iteration number 811360c497dSPeter Brune 812360c497dSPeter Brune Level: developer 813360c497dSPeter Brune 814360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number, 815360c497dSPeter Brune 816360c497dSPeter Brune .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 817360c497dSPeter Brune @*/ 818360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 819360c497dSPeter Brune { 820360c497dSPeter Brune PetscErrorCode ierr; 821360c497dSPeter Brune 822360c497dSPeter Brune PetscFunctionBegin; 823360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 824360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 825360c497dSPeter Brune snes->iter = iter; 826360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 827360c497dSPeter Brune PetscFunctionReturn(0); 828360c497dSPeter Brune } 829360c497dSPeter Brune 830360c497dSPeter Brune #undef __FUNCT__ 8314a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 8329b94acceSBarry Smith /*@ 8339b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 8349b94acceSBarry Smith with SNESSSetFunction(). 8359b94acceSBarry Smith 836c7afd0dbSLois Curfman McInnes Collective on SNES 837c7afd0dbSLois Curfman McInnes 8389b94acceSBarry Smith Input Parameter: 8399b94acceSBarry Smith . snes - SNES context 8409b94acceSBarry Smith 8419b94acceSBarry Smith Output Parameter: 8429b94acceSBarry Smith . fnorm - 2-norm of function 8439b94acceSBarry Smith 84436851e7fSLois Curfman McInnes Level: intermediate 84536851e7fSLois Curfman McInnes 8469b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 847a86d99e1SLois Curfman McInnes 848b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 8499b94acceSBarry Smith @*/ 8507087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 8519b94acceSBarry Smith { 8523a40ed3dSBarry Smith PetscFunctionBegin; 8530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8544482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 8559b94acceSBarry Smith *fnorm = snes->norm; 8563a40ed3dSBarry Smith PetscFunctionReturn(0); 8579b94acceSBarry Smith } 85874679c65SBarry Smith 859360c497dSPeter Brune 860360c497dSPeter Brune #undef __FUNCT__ 861360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm" 862360c497dSPeter Brune /*@ 863360c497dSPeter Brune SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm(). 864360c497dSPeter Brune 865360c497dSPeter Brune Collective on SNES 866360c497dSPeter Brune 867360c497dSPeter Brune Input Parameter: 868360c497dSPeter Brune . snes - SNES context 869360c497dSPeter Brune . fnorm - 2-norm of function 870360c497dSPeter Brune 871360c497dSPeter Brune Level: developer 872360c497dSPeter Brune 873360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm 874360c497dSPeter Brune 875360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm(). 876360c497dSPeter Brune @*/ 877360c497dSPeter Brune PetscErrorCode SNESSetFunctionNorm(SNES snes,PetscReal fnorm) 878360c497dSPeter Brune { 879360c497dSPeter Brune 880360c497dSPeter Brune PetscErrorCode ierr; 881360c497dSPeter Brune 882360c497dSPeter Brune PetscFunctionBegin; 883360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 884360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 885360c497dSPeter Brune snes->norm = fnorm; 886360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 887360c497dSPeter Brune PetscFunctionReturn(0); 888360c497dSPeter Brune } 889360c497dSPeter Brune 8904a2ae208SSatish Balay #undef __FUNCT__ 891b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 8929b94acceSBarry Smith /*@ 893b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 8949b94acceSBarry Smith attempted by the nonlinear solver. 8959b94acceSBarry Smith 896c7afd0dbSLois Curfman McInnes Not Collective 897c7afd0dbSLois Curfman McInnes 8989b94acceSBarry Smith Input Parameter: 8999b94acceSBarry Smith . snes - SNES context 9009b94acceSBarry Smith 9019b94acceSBarry Smith Output Parameter: 9029b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 9039b94acceSBarry Smith 904c96a6f78SLois Curfman McInnes Notes: 905c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 906c96a6f78SLois Curfman McInnes 90736851e7fSLois Curfman McInnes Level: intermediate 90836851e7fSLois Curfman McInnes 9099b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 91058ebbce7SBarry Smith 911e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 91258ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 9139b94acceSBarry Smith @*/ 9147087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 9159b94acceSBarry Smith { 9163a40ed3dSBarry Smith PetscFunctionBegin; 9170700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9184482741eSBarry Smith PetscValidIntPointer(nfails,2); 91950ffb88aSMatthew Knepley *nfails = snes->numFailures; 92050ffb88aSMatthew Knepley PetscFunctionReturn(0); 92150ffb88aSMatthew Knepley } 92250ffb88aSMatthew Knepley 92350ffb88aSMatthew Knepley #undef __FUNCT__ 924b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 92550ffb88aSMatthew Knepley /*@ 926b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 92750ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 92850ffb88aSMatthew Knepley 92950ffb88aSMatthew Knepley Not Collective 93050ffb88aSMatthew Knepley 93150ffb88aSMatthew Knepley Input Parameters: 93250ffb88aSMatthew Knepley + snes - SNES context 93350ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 93450ffb88aSMatthew Knepley 93550ffb88aSMatthew Knepley Level: intermediate 93650ffb88aSMatthew Knepley 93750ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 93858ebbce7SBarry Smith 939e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 94058ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 94150ffb88aSMatthew Knepley @*/ 9427087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 94350ffb88aSMatthew Knepley { 94450ffb88aSMatthew Knepley PetscFunctionBegin; 9450700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 94650ffb88aSMatthew Knepley snes->maxFailures = maxFails; 94750ffb88aSMatthew Knepley PetscFunctionReturn(0); 94850ffb88aSMatthew Knepley } 94950ffb88aSMatthew Knepley 95050ffb88aSMatthew Knepley #undef __FUNCT__ 951b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 95250ffb88aSMatthew Knepley /*@ 953b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 95450ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 95550ffb88aSMatthew Knepley 95650ffb88aSMatthew Knepley Not Collective 95750ffb88aSMatthew Knepley 95850ffb88aSMatthew Knepley Input Parameter: 95950ffb88aSMatthew Knepley . snes - SNES context 96050ffb88aSMatthew Knepley 96150ffb88aSMatthew Knepley Output Parameter: 96250ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 96350ffb88aSMatthew Knepley 96450ffb88aSMatthew Knepley Level: intermediate 96550ffb88aSMatthew Knepley 96650ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 96758ebbce7SBarry Smith 968e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 96958ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 97058ebbce7SBarry Smith 97150ffb88aSMatthew Knepley @*/ 9727087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 97350ffb88aSMatthew Knepley { 97450ffb88aSMatthew Knepley PetscFunctionBegin; 9750700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9764482741eSBarry Smith PetscValidIntPointer(maxFails,2); 97750ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 9783a40ed3dSBarry Smith PetscFunctionReturn(0); 9799b94acceSBarry Smith } 980a847f771SSatish Balay 9814a2ae208SSatish Balay #undef __FUNCT__ 9822541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 9832541af92SBarry Smith /*@ 9842541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 9852541af92SBarry Smith done by SNES. 9862541af92SBarry Smith 9872541af92SBarry Smith Not Collective 9882541af92SBarry Smith 9892541af92SBarry Smith Input Parameter: 9902541af92SBarry Smith . snes - SNES context 9912541af92SBarry Smith 9922541af92SBarry Smith Output Parameter: 9932541af92SBarry Smith . nfuncs - number of evaluations 9942541af92SBarry Smith 9952541af92SBarry Smith Level: intermediate 9962541af92SBarry Smith 9972541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 99858ebbce7SBarry Smith 999e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 10002541af92SBarry Smith @*/ 10017087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 10022541af92SBarry Smith { 10032541af92SBarry Smith PetscFunctionBegin; 10040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10052541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 10062541af92SBarry Smith *nfuncs = snes->nfuncs; 10072541af92SBarry Smith PetscFunctionReturn(0); 10082541af92SBarry Smith } 10092541af92SBarry Smith 10102541af92SBarry Smith #undef __FUNCT__ 10113d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 10123d4c4710SBarry Smith /*@ 10133d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 10143d4c4710SBarry Smith linear solvers. 10153d4c4710SBarry Smith 10163d4c4710SBarry Smith Not Collective 10173d4c4710SBarry Smith 10183d4c4710SBarry Smith Input Parameter: 10193d4c4710SBarry Smith . snes - SNES context 10203d4c4710SBarry Smith 10213d4c4710SBarry Smith Output Parameter: 10223d4c4710SBarry Smith . nfails - number of failed solves 10233d4c4710SBarry Smith 10243d4c4710SBarry Smith Notes: 10253d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 10263d4c4710SBarry Smith 10273d4c4710SBarry Smith Level: intermediate 10283d4c4710SBarry Smith 10293d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 103058ebbce7SBarry Smith 1031e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 10323d4c4710SBarry Smith @*/ 10337087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 10343d4c4710SBarry Smith { 10353d4c4710SBarry Smith PetscFunctionBegin; 10360700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10373d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 10383d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 10393d4c4710SBarry Smith PetscFunctionReturn(0); 10403d4c4710SBarry Smith } 10413d4c4710SBarry Smith 10423d4c4710SBarry Smith #undef __FUNCT__ 10433d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 10443d4c4710SBarry Smith /*@ 10453d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 10463d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 10473d4c4710SBarry Smith 10483f9fe445SBarry Smith Logically Collective on SNES 10493d4c4710SBarry Smith 10503d4c4710SBarry Smith Input Parameters: 10513d4c4710SBarry Smith + snes - SNES context 10523d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 10533d4c4710SBarry Smith 10543d4c4710SBarry Smith Level: intermediate 10553d4c4710SBarry Smith 1056a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 10573d4c4710SBarry Smith 10583d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 10593d4c4710SBarry Smith 106058ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 10613d4c4710SBarry Smith @*/ 10627087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 10633d4c4710SBarry Smith { 10643d4c4710SBarry Smith PetscFunctionBegin; 10650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1066c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 10673d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 10683d4c4710SBarry Smith PetscFunctionReturn(0); 10693d4c4710SBarry Smith } 10703d4c4710SBarry Smith 10713d4c4710SBarry Smith #undef __FUNCT__ 10723d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 10733d4c4710SBarry Smith /*@ 10743d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 10753d4c4710SBarry Smith are allowed before SNES terminates 10763d4c4710SBarry Smith 10773d4c4710SBarry Smith Not Collective 10783d4c4710SBarry Smith 10793d4c4710SBarry Smith Input Parameter: 10803d4c4710SBarry Smith . snes - SNES context 10813d4c4710SBarry Smith 10823d4c4710SBarry Smith Output Parameter: 10833d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 10843d4c4710SBarry Smith 10853d4c4710SBarry Smith Level: intermediate 10863d4c4710SBarry Smith 10873d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 10883d4c4710SBarry Smith 10893d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 10903d4c4710SBarry Smith 1091e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 10923d4c4710SBarry Smith @*/ 10937087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 10943d4c4710SBarry Smith { 10953d4c4710SBarry Smith PetscFunctionBegin; 10960700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10973d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 10983d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 10993d4c4710SBarry Smith PetscFunctionReturn(0); 11003d4c4710SBarry Smith } 11013d4c4710SBarry Smith 11023d4c4710SBarry Smith #undef __FUNCT__ 1103b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 1104c96a6f78SLois Curfman McInnes /*@ 1105b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1106c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1107c96a6f78SLois Curfman McInnes 1108c7afd0dbSLois Curfman McInnes Not Collective 1109c7afd0dbSLois Curfman McInnes 1110c96a6f78SLois Curfman McInnes Input Parameter: 1111c96a6f78SLois Curfman McInnes . snes - SNES context 1112c96a6f78SLois Curfman McInnes 1113c96a6f78SLois Curfman McInnes Output Parameter: 1114c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1115c96a6f78SLois Curfman McInnes 1116c96a6f78SLois Curfman McInnes Notes: 1117c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1118c96a6f78SLois Curfman McInnes 111936851e7fSLois Curfman McInnes Level: intermediate 112036851e7fSLois Curfman McInnes 1121c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 11222b668275SBarry Smith 11238c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 1124c96a6f78SLois Curfman McInnes @*/ 11257087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 1126c96a6f78SLois Curfman McInnes { 11273a40ed3dSBarry Smith PetscFunctionBegin; 11280700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11294482741eSBarry Smith PetscValidIntPointer(lits,2); 1130c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 11313a40ed3dSBarry Smith PetscFunctionReturn(0); 1132c96a6f78SLois Curfman McInnes } 1133c96a6f78SLois Curfman McInnes 11344a2ae208SSatish Balay #undef __FUNCT__ 113594b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 113652baeb72SSatish Balay /*@ 113794b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 11389b94acceSBarry Smith 113994b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 1140c7afd0dbSLois Curfman McInnes 11419b94acceSBarry Smith Input Parameter: 11429b94acceSBarry Smith . snes - the SNES context 11439b94acceSBarry Smith 11449b94acceSBarry Smith Output Parameter: 114594b7f48cSBarry Smith . ksp - the KSP context 11469b94acceSBarry Smith 11479b94acceSBarry Smith Notes: 114894b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 11499b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 11502999313aSBarry Smith PC contexts as well. 11519b94acceSBarry Smith 115236851e7fSLois Curfman McInnes Level: beginner 115336851e7fSLois Curfman McInnes 115494b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 11559b94acceSBarry Smith 11562999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 11579b94acceSBarry Smith @*/ 11587087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 11599b94acceSBarry Smith { 11601cee3971SBarry Smith PetscErrorCode ierr; 11611cee3971SBarry Smith 11623a40ed3dSBarry Smith PetscFunctionBegin; 11630700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11644482741eSBarry Smith PetscValidPointer(ksp,2); 11651cee3971SBarry Smith 11661cee3971SBarry Smith if (!snes->ksp) { 11671cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 11681cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 11691cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 11701cee3971SBarry Smith } 117194b7f48cSBarry Smith *ksp = snes->ksp; 11723a40ed3dSBarry Smith PetscFunctionReturn(0); 11739b94acceSBarry Smith } 117482bf6240SBarry Smith 11754a2ae208SSatish Balay #undef __FUNCT__ 11762999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 11772999313aSBarry Smith /*@ 11782999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 11792999313aSBarry Smith 11802999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 11812999313aSBarry Smith 11822999313aSBarry Smith Input Parameters: 11832999313aSBarry Smith + snes - the SNES context 11842999313aSBarry Smith - ksp - the KSP context 11852999313aSBarry Smith 11862999313aSBarry Smith Notes: 11872999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 11882999313aSBarry Smith so this routine is rarely needed. 11892999313aSBarry Smith 11902999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 11912999313aSBarry Smith decreased by one. 11922999313aSBarry Smith 11932999313aSBarry Smith Level: developer 11942999313aSBarry Smith 11952999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 11962999313aSBarry Smith 11972999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 11982999313aSBarry Smith @*/ 11997087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 12002999313aSBarry Smith { 12012999313aSBarry Smith PetscErrorCode ierr; 12022999313aSBarry Smith 12032999313aSBarry Smith PetscFunctionBegin; 12040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12050700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 12062999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 12077dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1208906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 12092999313aSBarry Smith snes->ksp = ksp; 12102999313aSBarry Smith PetscFunctionReturn(0); 12112999313aSBarry Smith } 12122999313aSBarry Smith 12137adad957SLisandro Dalcin #if 0 12142999313aSBarry Smith #undef __FUNCT__ 12154a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 12166849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1217e24b481bSBarry Smith { 1218e24b481bSBarry Smith PetscFunctionBegin; 1219e24b481bSBarry Smith PetscFunctionReturn(0); 1220e24b481bSBarry Smith } 12217adad957SLisandro Dalcin #endif 1222e24b481bSBarry Smith 12239b94acceSBarry Smith /* -----------------------------------------------------------*/ 12244a2ae208SSatish Balay #undef __FUNCT__ 12254a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 122652baeb72SSatish Balay /*@ 12279b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 12289b94acceSBarry Smith 1229c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1230c7afd0dbSLois Curfman McInnes 1231c7afd0dbSLois Curfman McInnes Input Parameters: 1232906ed7ccSBarry Smith . comm - MPI communicator 12339b94acceSBarry Smith 12349b94acceSBarry Smith Output Parameter: 12359b94acceSBarry Smith . outsnes - the new SNES context 12369b94acceSBarry Smith 1237c7afd0dbSLois Curfman McInnes Options Database Keys: 1238c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1239c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1240c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1241c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1242c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1243c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1244c1f60f51SBarry Smith 124536851e7fSLois Curfman McInnes Level: beginner 124636851e7fSLois Curfman McInnes 12479b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 12489b94acceSBarry Smith 1249a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1250a8054027SBarry Smith 12519b94acceSBarry Smith @*/ 12527087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 12539b94acceSBarry Smith { 1254dfbe8321SBarry Smith PetscErrorCode ierr; 12559b94acceSBarry Smith SNES snes; 1256fa9f3622SBarry Smith SNESKSPEW *kctx; 125737fcc0dbSBarry Smith 12583a40ed3dSBarry Smith PetscFunctionBegin; 1259ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 12608ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 12618ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 12628ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 12638ba1e511SMatthew Knepley #endif 12648ba1e511SMatthew Knepley 12653194b578SJed Brown ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 12667adad957SLisandro Dalcin 126785385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 12682c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 12699b94acceSBarry Smith snes->max_its = 50; 12709750a799SBarry Smith snes->max_funcs = 10000; 12719b94acceSBarry Smith snes->norm = 0.0; 1272b4874afaSBarry Smith snes->rtol = 1.e-8; 1273b4874afaSBarry Smith snes->ttol = 0.0; 127470441072SBarry Smith snes->abstol = 1.e-50; 1275*c60f73f4SPeter Brune snes->stol = 1.e-8; 12764b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 12779b94acceSBarry Smith snes->nfuncs = 0; 127850ffb88aSMatthew Knepley snes->numFailures = 0; 127950ffb88aSMatthew Knepley snes->maxFailures = 1; 12807a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1281e35cf81dSBarry Smith snes->lagjacobian = 1; 1282a8054027SBarry Smith snes->lagpreconditioner = 1; 1283639f9d9dSBarry Smith snes->numbermonitors = 0; 12849b94acceSBarry Smith snes->data = 0; 12854dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1286186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 12876f24a144SLois Curfman McInnes snes->nwork = 0; 128858c9b817SLisandro Dalcin snes->work = 0; 128958c9b817SLisandro Dalcin snes->nvwork = 0; 129058c9b817SLisandro Dalcin snes->vwork = 0; 1291758f92a0SBarry Smith snes->conv_hist_len = 0; 1292758f92a0SBarry Smith snes->conv_hist_max = 0; 1293758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1294758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1295758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1296184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 129789b92e6fSPeter Brune snes->gssweeps = 1; 12989b94acceSBarry Smith 12993d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 13003d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 13013d4c4710SBarry Smith 13029b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 130338f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 13049b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 13059b94acceSBarry Smith kctx->version = 2; 13069b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 13079b94acceSBarry Smith this was too large for some test cases */ 130875567043SBarry Smith kctx->rtol_last = 0.0; 13099b94acceSBarry Smith kctx->rtol_max = .9; 13109b94acceSBarry Smith kctx->gamma = 1.0; 131162d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 131271f87433Sdalcinl kctx->alpha2 = kctx->alpha; 13139b94acceSBarry Smith kctx->threshold = .1; 131475567043SBarry Smith kctx->lresid_last = 0.0; 131575567043SBarry Smith kctx->norm_last = 0.0; 13169b94acceSBarry Smith 13179b94acceSBarry Smith *outsnes = snes; 13183a40ed3dSBarry Smith PetscFunctionReturn(0); 13199b94acceSBarry Smith } 13209b94acceSBarry Smith 13214a2ae208SSatish Balay #undef __FUNCT__ 13224a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 13239b94acceSBarry Smith /*@C 13249b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 13259b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 13269b94acceSBarry Smith equations. 13279b94acceSBarry Smith 13283f9fe445SBarry Smith Logically Collective on SNES 1329fee21e36SBarry Smith 1330c7afd0dbSLois Curfman McInnes Input Parameters: 1331c7afd0dbSLois Curfman McInnes + snes - the SNES context 1332c7afd0dbSLois Curfman McInnes . r - vector to store function value 1333de044059SHong Zhang . func - function evaluation routine 1334c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1335c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 13369b94acceSBarry Smith 1337c7afd0dbSLois Curfman McInnes Calling sequence of func: 13388d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1339c7afd0dbSLois Curfman McInnes 1340c586c404SJed Brown + snes - the SNES context 1341c586c404SJed Brown . x - state at which to evaluate residual 1342c586c404SJed Brown . f - vector to put residual 1343c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 13449b94acceSBarry Smith 13459b94acceSBarry Smith Notes: 13469b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 13479b94acceSBarry Smith $ f'(x) x = -f(x), 1348c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 13499b94acceSBarry Smith 135036851e7fSLois Curfman McInnes Level: beginner 135136851e7fSLois Curfman McInnes 13529b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 13539b94acceSBarry Smith 13548b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard() 13559b94acceSBarry Smith @*/ 13567087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 13579b94acceSBarry Smith { 135885385478SLisandro Dalcin PetscErrorCode ierr; 13596cab3a1bSJed Brown DM dm; 13606cab3a1bSJed Brown 13613a40ed3dSBarry Smith PetscFunctionBegin; 13620700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1363d2a683ecSLisandro Dalcin if (r) { 1364d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1365d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 136685385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 13676bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 136885385478SLisandro Dalcin snes->vec_func = r; 1369d2a683ecSLisandro Dalcin } 13706cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 13716cab3a1bSJed Brown ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr); 13723a40ed3dSBarry Smith PetscFunctionReturn(0); 13739b94acceSBarry Smith } 13749b94acceSBarry Smith 1375646217ecSPeter Brune 1376646217ecSPeter Brune #undef __FUNCT__ 1377646217ecSPeter Brune #define __FUNCT__ "SNESSetGS" 1378c79ef259SPeter Brune /*@C 1379c79ef259SPeter Brune SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for 1380c79ef259SPeter Brune use with composed nonlinear solvers. 1381c79ef259SPeter Brune 1382c79ef259SPeter Brune Input Parameters: 1383c79ef259SPeter Brune + snes - the SNES context 1384c79ef259SPeter Brune . gsfunc - function evaluation routine 1385c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 1386c79ef259SPeter Brune smoother evaluation routine (may be PETSC_NULL) 1387c79ef259SPeter Brune 1388c79ef259SPeter Brune Calling sequence of func: 1389c79ef259SPeter Brune $ func (SNES snes,Vec x,Vec b,void *ctx); 1390c79ef259SPeter Brune 1391c79ef259SPeter Brune + X - solution vector 1392c79ef259SPeter Brune . B - RHS vector 1393d28543b3SPeter Brune - ctx - optional user-defined Gauss-Seidel context 1394c79ef259SPeter Brune 1395c79ef259SPeter Brune Notes: 1396c79ef259SPeter Brune The GS routines are used by the composed nonlinear solver to generate 1397c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1398c79ef259SPeter Brune 1399d28543b3SPeter Brune Level: intermediate 1400c79ef259SPeter Brune 1401d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1402c79ef259SPeter Brune 1403c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS() 1404c79ef259SPeter Brune @*/ 14056cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx) 14066cab3a1bSJed Brown { 14076cab3a1bSJed Brown PetscErrorCode ierr; 14086cab3a1bSJed Brown DM dm; 14096cab3a1bSJed Brown 1410646217ecSPeter Brune PetscFunctionBegin; 14116cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14126cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 14136cab3a1bSJed Brown ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr); 1414646217ecSPeter Brune PetscFunctionReturn(0); 1415646217ecSPeter Brune } 1416646217ecSPeter Brune 1417d25893d9SBarry Smith #undef __FUNCT__ 141889b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps" 141989b92e6fSPeter Brune /*@ 142089b92e6fSPeter Brune SNESSetGSSweeps - Sets the number of sweeps of GS to use. 142189b92e6fSPeter Brune 142289b92e6fSPeter Brune Input Parameters: 142389b92e6fSPeter Brune + snes - the SNES context 142489b92e6fSPeter Brune - sweeps - the number of sweeps of GS to perform. 142589b92e6fSPeter Brune 142689b92e6fSPeter Brune Level: intermediate 142789b92e6fSPeter Brune 142889b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 142989b92e6fSPeter Brune 143089b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps() 143189b92e6fSPeter Brune @*/ 143289b92e6fSPeter Brune 143389b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) { 143489b92e6fSPeter Brune PetscFunctionBegin; 143589b92e6fSPeter Brune snes->gssweeps = sweeps; 143689b92e6fSPeter Brune PetscFunctionReturn(0); 143789b92e6fSPeter Brune } 143889b92e6fSPeter Brune 143989b92e6fSPeter Brune 144089b92e6fSPeter Brune #undef __FUNCT__ 144189b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps" 144289b92e6fSPeter Brune /*@ 144389b92e6fSPeter Brune SNESGetGSSweeps - Gets the number of sweeps GS will use. 144489b92e6fSPeter Brune 144589b92e6fSPeter Brune Input Parameters: 144689b92e6fSPeter Brune . snes - the SNES context 144789b92e6fSPeter Brune 144889b92e6fSPeter Brune Output Parameters: 144989b92e6fSPeter Brune . sweeps - the number of sweeps of GS to perform. 145089b92e6fSPeter Brune 145189b92e6fSPeter Brune Level: intermediate 145289b92e6fSPeter Brune 145389b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 145489b92e6fSPeter Brune 145589b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps() 145689b92e6fSPeter Brune @*/ 145789b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) { 145889b92e6fSPeter Brune PetscFunctionBegin; 145989b92e6fSPeter Brune *sweeps = snes->gssweeps; 146089b92e6fSPeter Brune PetscFunctionReturn(0); 146189b92e6fSPeter Brune } 146289b92e6fSPeter Brune 146389b92e6fSPeter Brune #undef __FUNCT__ 14648b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 14658b0a5094SBarry Smith PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 14668b0a5094SBarry Smith { 14678b0a5094SBarry Smith PetscErrorCode ierr; 14686cab3a1bSJed Brown void *functx,*jacctx; 14696cab3a1bSJed Brown 14708b0a5094SBarry Smith PetscFunctionBegin; 14716cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 14726cab3a1bSJed Brown ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr); 14738b0a5094SBarry Smith /* A(x)*x - b(x) */ 14746cab3a1bSJed Brown ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr); 14756cab3a1bSJed Brown ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr); 14768b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 14778b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 14788b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 14798b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 14808b0a5094SBarry Smith PetscFunctionReturn(0); 14818b0a5094SBarry Smith } 14828b0a5094SBarry Smith 14838b0a5094SBarry Smith #undef __FUNCT__ 14848b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 14858b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 14868b0a5094SBarry Smith { 14878b0a5094SBarry Smith PetscFunctionBegin; 14888b0a5094SBarry Smith *flag = snes->matstruct; 14898b0a5094SBarry Smith PetscFunctionReturn(0); 14908b0a5094SBarry Smith } 14918b0a5094SBarry Smith 14928b0a5094SBarry Smith #undef __FUNCT__ 14938b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 14948b0a5094SBarry Smith /*@C 14950d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 14968b0a5094SBarry Smith 14978b0a5094SBarry Smith Logically Collective on SNES 14988b0a5094SBarry Smith 14998b0a5094SBarry Smith Input Parameters: 15008b0a5094SBarry Smith + snes - the SNES context 15018b0a5094SBarry Smith . r - vector to store function value 15028b0a5094SBarry Smith . func - function evaluation routine 15038b0a5094SBarry Smith . jmat - normally the same as mat but you can pass another matrix for which you compute the Jacobian of A(x) x - b(x) (see jmat below) 15048b0a5094SBarry Smith . mat - matrix to store A 15058b0a5094SBarry Smith . mfunc - function to compute matrix value 15068b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 15078b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 15088b0a5094SBarry Smith 15098b0a5094SBarry Smith Calling sequence of func: 15108b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 15118b0a5094SBarry Smith 15128b0a5094SBarry Smith + f - function vector 15138b0a5094SBarry Smith - ctx - optional user-defined function context 15148b0a5094SBarry Smith 15158b0a5094SBarry Smith Calling sequence of mfunc: 15168b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 15178b0a5094SBarry Smith 15188b0a5094SBarry Smith + x - input vector 15198b0a5094SBarry Smith . jmat - Form Jacobian matrix of A(x) x - b(x) if available, not there is really no reason to use it in this way since then you can just use SNESSetJacobian(), 15208b0a5094SBarry Smith normally just pass mat in this location 15218b0a5094SBarry Smith . mat - form A(x) matrix 15228b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 15238b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 15248b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 15258b0a5094SBarry Smith 15268b0a5094SBarry Smith Notes: 15278b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 15288b0a5094SBarry Smith 15298b0a5094SBarry Smith $ Solves the equation A(x) x = b(x) via the defect correction algorithm A(x^{n}) (x^{n+1} - x^{n}) = b(x^{n}) - A(x^{n})x^{n} 15308b0a5094SBarry Smith $ Note that when an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = b(x^{n}) iteration. 15318b0a5094SBarry Smith 15328b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 15338b0a5094SBarry Smith 15340d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 15350d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 15368b0a5094SBarry Smith 15378b0a5094SBarry Smith There is some controversity over the definition of a Picard iteration for nonlinear systems but almost everyone agrees that it involves a linear solve and some 15388b0a5094SBarry Smith believe it is the iteration A(x^{n}) x^{n+1} = b(x^{n}) hence we use the name Picard. If anyone has an authoritative reference that defines the Picard iteration 15398b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 15408b0a5094SBarry Smith 15418b0a5094SBarry Smith Level: beginner 15428b0a5094SBarry Smith 15438b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 15448b0a5094SBarry Smith 15450d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard() 15468b0a5094SBarry Smith @*/ 15478b0a5094SBarry Smith PetscErrorCode SNESSetPicard(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),Mat jmat, Mat mat, PetscErrorCode (*mfunc)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 15488b0a5094SBarry Smith { 15498b0a5094SBarry Smith PetscErrorCode ierr; 15508b0a5094SBarry Smith PetscFunctionBegin; 15518b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15528b0a5094SBarry Smith snes->ops->computepfunction = func; 15538b0a5094SBarry Smith snes->ops->computepjacobian = mfunc; 15548b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 15558b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 15568b0a5094SBarry Smith PetscFunctionReturn(0); 15578b0a5094SBarry Smith } 15588b0a5094SBarry Smith 15598b0a5094SBarry Smith #undef __FUNCT__ 1560d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1561d25893d9SBarry Smith /*@C 1562d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1563d25893d9SBarry Smith 1564d25893d9SBarry Smith Logically Collective on SNES 1565d25893d9SBarry Smith 1566d25893d9SBarry Smith Input Parameters: 1567d25893d9SBarry Smith + snes - the SNES context 1568d25893d9SBarry Smith . func - function evaluation routine 1569d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1570d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1571d25893d9SBarry Smith 1572d25893d9SBarry Smith Calling sequence of func: 1573d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1574d25893d9SBarry Smith 1575d25893d9SBarry Smith . f - function vector 1576d25893d9SBarry Smith - ctx - optional user-defined function context 1577d25893d9SBarry Smith 1578d25893d9SBarry Smith Level: intermediate 1579d25893d9SBarry Smith 1580d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1581d25893d9SBarry Smith 1582d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1583d25893d9SBarry Smith @*/ 1584d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1585d25893d9SBarry Smith { 1586d25893d9SBarry Smith PetscFunctionBegin; 1587d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1588d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1589d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1590d25893d9SBarry Smith PetscFunctionReturn(0); 1591d25893d9SBarry Smith } 1592d25893d9SBarry Smith 15933ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 15943ab0aad5SBarry Smith #undef __FUNCT__ 15951096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 15961096aae1SMatthew Knepley /*@C 15971096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 15981096aae1SMatthew Knepley it assumes a zero right hand side. 15991096aae1SMatthew Knepley 16003f9fe445SBarry Smith Logically Collective on SNES 16011096aae1SMatthew Knepley 16021096aae1SMatthew Knepley Input Parameter: 16031096aae1SMatthew Knepley . snes - the SNES context 16041096aae1SMatthew Knepley 16051096aae1SMatthew Knepley Output Parameter: 1606bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 16071096aae1SMatthew Knepley 16081096aae1SMatthew Knepley Level: intermediate 16091096aae1SMatthew Knepley 16101096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 16111096aae1SMatthew Knepley 161285385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 16131096aae1SMatthew Knepley @*/ 16147087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 16151096aae1SMatthew Knepley { 16161096aae1SMatthew Knepley PetscFunctionBegin; 16170700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16181096aae1SMatthew Knepley PetscValidPointer(rhs,2); 161985385478SLisandro Dalcin *rhs = snes->vec_rhs; 16201096aae1SMatthew Knepley PetscFunctionReturn(0); 16211096aae1SMatthew Knepley } 16221096aae1SMatthew Knepley 16231096aae1SMatthew Knepley #undef __FUNCT__ 16244a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 16259b94acceSBarry Smith /*@ 162636851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 16279b94acceSBarry Smith SNESSetFunction(). 16289b94acceSBarry Smith 1629c7afd0dbSLois Curfman McInnes Collective on SNES 1630c7afd0dbSLois Curfman McInnes 16319b94acceSBarry Smith Input Parameters: 1632c7afd0dbSLois Curfman McInnes + snes - the SNES context 1633c7afd0dbSLois Curfman McInnes - x - input vector 16349b94acceSBarry Smith 16359b94acceSBarry Smith Output Parameter: 16363638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 16379b94acceSBarry Smith 16381bffabb2SLois Curfman McInnes Notes: 163936851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 164036851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 164136851e7fSLois Curfman McInnes themselves. 164236851e7fSLois Curfman McInnes 164336851e7fSLois Curfman McInnes Level: developer 164436851e7fSLois Curfman McInnes 16459b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 16469b94acceSBarry Smith 1647a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 16489b94acceSBarry Smith @*/ 16497087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 16509b94acceSBarry Smith { 1651dfbe8321SBarry Smith PetscErrorCode ierr; 16526cab3a1bSJed Brown DM dm; 16536cab3a1bSJed Brown SNESDM sdm; 16549b94acceSBarry Smith 16553a40ed3dSBarry Smith PetscFunctionBegin; 16560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16570700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 16580700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1659c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1660c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 16614ec14c9cSBarry Smith VecValidValues(x,2,PETSC_TRUE); 1662184914b5SBarry Smith 16636cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 16646cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 1665d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 16666cab3a1bSJed Brown if (sdm->computefunction) { 1667d64ed03dSBarry Smith PetscStackPush("SNES user function"); 16686cab3a1bSJed Brown ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 1669d64ed03dSBarry Smith PetscStackPop; 167073250ac0SBarry Smith } else if (snes->dm) { 1671644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1672c90fad12SPeter Brune } else if (snes->vec_rhs) { 1673c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1674644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 167585385478SLisandro Dalcin if (snes->vec_rhs) { 167685385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 16773ab0aad5SBarry Smith } 1678ae3c334cSLois Curfman McInnes snes->nfuncs++; 1679d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 16804ec14c9cSBarry Smith VecValidValues(y,3,PETSC_FALSE); 16813a40ed3dSBarry Smith PetscFunctionReturn(0); 16829b94acceSBarry Smith } 16839b94acceSBarry Smith 16844a2ae208SSatish Balay #undef __FUNCT__ 1685646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1686c79ef259SPeter Brune /*@ 1687c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1688c79ef259SPeter Brune SNESSetGS(). 1689c79ef259SPeter Brune 1690c79ef259SPeter Brune Collective on SNES 1691c79ef259SPeter Brune 1692c79ef259SPeter Brune Input Parameters: 1693c79ef259SPeter Brune + snes - the SNES context 1694c79ef259SPeter Brune . x - input vector 1695c79ef259SPeter Brune - b - rhs vector 1696c79ef259SPeter Brune 1697c79ef259SPeter Brune Output Parameter: 1698c79ef259SPeter Brune . x - new solution vector 1699c79ef259SPeter Brune 1700c79ef259SPeter Brune Notes: 1701c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1702c79ef259SPeter Brune implementations, so most users would not generally call this routine 1703c79ef259SPeter Brune themselves. 1704c79ef259SPeter Brune 1705c79ef259SPeter Brune Level: developer 1706c79ef259SPeter Brune 1707c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1708c79ef259SPeter Brune 1709c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1710c79ef259SPeter Brune @*/ 1711646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1712646217ecSPeter Brune { 1713646217ecSPeter Brune PetscErrorCode ierr; 171489b92e6fSPeter Brune PetscInt i; 17156cab3a1bSJed Brown DM dm; 17166cab3a1bSJed Brown SNESDM sdm; 1717646217ecSPeter Brune 1718646217ecSPeter Brune PetscFunctionBegin; 1719646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1720646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1721646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1722646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 1723646217ecSPeter Brune if(b) PetscCheckSameComm(snes,1,b,3); 17244ec14c9cSBarry Smith if (b) VecValidValues(b,2,PETSC_TRUE); 1725701cf23dSPeter Brune ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 17266cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 17276cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 17286cab3a1bSJed Brown if (sdm->computegs) { 172989b92e6fSPeter Brune for (i = 0; i < snes->gssweeps; i++) { 1730646217ecSPeter Brune PetscStackPush("SNES user GS"); 17316cab3a1bSJed Brown ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 1732646217ecSPeter Brune PetscStackPop; 173389b92e6fSPeter Brune } 1734646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 1735701cf23dSPeter Brune ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 17364ec14c9cSBarry Smith VecValidValues(x,3,PETSC_FALSE); 1737646217ecSPeter Brune PetscFunctionReturn(0); 1738646217ecSPeter Brune } 1739646217ecSPeter Brune 1740646217ecSPeter Brune 1741646217ecSPeter Brune #undef __FUNCT__ 17424a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 174362fef451SLois Curfman McInnes /*@ 174462fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 174562fef451SLois Curfman McInnes set with SNESSetJacobian(). 174662fef451SLois Curfman McInnes 1747c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1748c7afd0dbSLois Curfman McInnes 174962fef451SLois Curfman McInnes Input Parameters: 1750c7afd0dbSLois Curfman McInnes + snes - the SNES context 1751c7afd0dbSLois Curfman McInnes - x - input vector 175262fef451SLois Curfman McInnes 175362fef451SLois Curfman McInnes Output Parameters: 1754c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 175562fef451SLois Curfman McInnes . B - optional preconditioning matrix 17562b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1757fee21e36SBarry Smith 1758e35cf81dSBarry Smith Options Database Keys: 1759e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1760693365a8SJed Brown . -snes_lag_jacobian <lag> 1761693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1762693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1763693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 17644c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1765c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 1766c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 1767c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 1768c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 1769c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 17704c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 1771c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 1772c01495d3SJed Brown 1773e35cf81dSBarry Smith 177462fef451SLois Curfman McInnes Notes: 177562fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 177662fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 177762fef451SLois Curfman McInnes 177894b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1779dc5a77f8SLois Curfman McInnes flag parameter. 178062fef451SLois Curfman McInnes 178136851e7fSLois Curfman McInnes Level: developer 178236851e7fSLois Curfman McInnes 178362fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 178462fef451SLois Curfman McInnes 1785e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 178662fef451SLois Curfman McInnes @*/ 17877087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 17889b94acceSBarry Smith { 1789dfbe8321SBarry Smith PetscErrorCode ierr; 1790ace3abfcSBarry Smith PetscBool flag; 17916cab3a1bSJed Brown DM dm; 17926cab3a1bSJed Brown SNESDM sdm; 17933a40ed3dSBarry Smith 17943a40ed3dSBarry Smith PetscFunctionBegin; 17950700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 17960700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 17974482741eSBarry Smith PetscValidPointer(flg,5); 1798c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 17994ec14c9cSBarry Smith VecValidValues(X,2,PETSC_TRUE); 18006cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18016cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 18026cab3a1bSJed Brown if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 1803ebd3b9afSBarry Smith 1804ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1805ebd3b9afSBarry Smith 1806fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 1807fe3ffe1eSBarry Smith snes->lagjacobian = -1; 1808fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1809fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 1810e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1811e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1812ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1813ebd3b9afSBarry Smith if (flag) { 1814ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1815ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1816ebd3b9afSBarry Smith } 1817e35cf81dSBarry Smith PetscFunctionReturn(0); 1818e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1819e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1820e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1821ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1822ebd3b9afSBarry Smith if (flag) { 1823ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1824ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1825ebd3b9afSBarry Smith } 1826e35cf81dSBarry Smith PetscFunctionReturn(0); 1827e35cf81dSBarry Smith } 1828e35cf81dSBarry Smith 1829c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 1830e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1831d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 18326cab3a1bSJed Brown ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr); 1833d64ed03dSBarry Smith PetscStackPop; 1834d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1835a8054027SBarry Smith 18363b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 18373b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 18383b4f5425SBarry Smith snes->lagpreconditioner = -1; 18393b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 1840a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1841a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 1842a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 1843a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1844a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 1845a8054027SBarry Smith } 1846a8054027SBarry Smith 18476d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 18480700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 18490700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 1850693365a8SJed Brown { 1851693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 1852693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 1853693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 1854693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 1855693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 1856693365a8SJed Brown if (flag || flag_draw || flag_contour) { 1857693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 1858693365a8SJed Brown MatStructure mstruct; 1859693365a8SJed Brown PetscViewer vdraw,vstdout; 18606b3a5b13SJed Brown PetscBool flg; 1861693365a8SJed Brown if (flag_operator) { 1862693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 1863693365a8SJed Brown Bexp = Bexp_mine; 1864693365a8SJed Brown } else { 1865693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 1866693365a8SJed Brown ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 1867693365a8SJed Brown if (flg) Bexp = *B; 1868693365a8SJed Brown else { 1869693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 1870693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 1871693365a8SJed Brown Bexp = Bexp_mine; 1872693365a8SJed Brown } 1873693365a8SJed Brown } 1874693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 1875693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 1876693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 1877693365a8SJed Brown if (flag_draw || flag_contour) { 1878693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 1879693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 1880693365a8SJed Brown } else vdraw = PETSC_NULL; 1881693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 1882693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 1883693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 1884693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 1885693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1886693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 1887693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1888693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 1889693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1890693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 1891693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 1892693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 1893693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 1894693365a8SJed Brown } 1895693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 1896693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 1897693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 1898693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 1899693365a8SJed Brown } 1900693365a8SJed Brown } 19014c30e9fbSJed Brown { 19026719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 19036719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 19044c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 19056719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 19064c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 19074c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 19086719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 19096719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 19106719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 19116719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 19124c30e9fbSJed Brown Mat Bfd; 19134c30e9fbSJed Brown MatStructure mstruct; 19144c30e9fbSJed Brown PetscViewer vdraw,vstdout; 19154c30e9fbSJed Brown ISColoring iscoloring; 19164c30e9fbSJed Brown MatFDColoring matfdcoloring; 19174c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 19184c30e9fbSJed Brown void *funcctx; 19196719d8e4SJed Brown PetscReal norm1,norm2,normmax; 19204c30e9fbSJed Brown 19214c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 19224c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 19234c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 19244c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 19254c30e9fbSJed Brown 19264c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 19274c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 19284c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 19294c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 19304c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 19314c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 19324c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 19334c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 19344c30e9fbSJed Brown 19354c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 19364c30e9fbSJed Brown if (flag_draw || flag_contour) { 19374c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 19384c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 19394c30e9fbSJed Brown } else vdraw = PETSC_NULL; 19404c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 19416719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 19424c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 19434c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 19446719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 19454c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 19464c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 19474c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 19486719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 19494c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 19506719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 19516719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 19524c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 19534c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 19544c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 19554c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 19564c30e9fbSJed Brown } 19574c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 19586719d8e4SJed Brown 19596719d8e4SJed Brown if (flag_threshold) { 19606719d8e4SJed Brown PetscInt bs,rstart,rend,i; 19616719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 19626719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 19636719d8e4SJed Brown for (i=rstart; i<rend; i++) { 19646719d8e4SJed Brown const PetscScalar *ba,*ca; 19656719d8e4SJed Brown const PetscInt *bj,*cj; 19666719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 19676719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 19686719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 19696719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 19706719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 19716719d8e4SJed Brown for (j=0; j<bn; j++) { 19726719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 19736719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 19746719d8e4SJed Brown maxentrycol = bj[j]; 19756719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 19766719d8e4SJed Brown } 19776719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 19786719d8e4SJed Brown maxdiffcol = bj[j]; 19796719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 19806719d8e4SJed Brown } 19816719d8e4SJed Brown if (rdiff > maxrdiff) { 19826719d8e4SJed Brown maxrdiffcol = bj[j]; 19836719d8e4SJed Brown maxrdiff = rdiff; 19846719d8e4SJed Brown } 19856719d8e4SJed Brown } 19866719d8e4SJed Brown if (maxrdiff > 1) { 19876719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"row %D (maxentry=%G at %D, maxdiff=%G at %D, maxrdiff=%G at %D):",i,maxentry,maxentrycol,maxdiff,maxdiffcol,maxrdiff,maxrdiffcol);CHKERRQ(ierr); 19886719d8e4SJed Brown for (j=0; j<bn; j++) { 19896719d8e4SJed Brown PetscReal rdiff; 19906719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 19916719d8e4SJed Brown if (rdiff > 1) { 19926719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 19936719d8e4SJed Brown } 19946719d8e4SJed Brown } 19956719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 19966719d8e4SJed Brown } 19976719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 19986719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 19996719d8e4SJed Brown } 20006719d8e4SJed Brown } 20014c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 20024c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 20034c30e9fbSJed Brown } 20044c30e9fbSJed Brown } 20053a40ed3dSBarry Smith PetscFunctionReturn(0); 20069b94acceSBarry Smith } 20079b94acceSBarry Smith 20084a2ae208SSatish Balay #undef __FUNCT__ 20094a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 20109b94acceSBarry Smith /*@C 20119b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2012044dda88SLois Curfman McInnes location to store the matrix. 20139b94acceSBarry Smith 20143f9fe445SBarry Smith Logically Collective on SNES and Mat 2015c7afd0dbSLois Curfman McInnes 20169b94acceSBarry Smith Input Parameters: 2017c7afd0dbSLois Curfman McInnes + snes - the SNES context 20189b94acceSBarry Smith . A - Jacobian matrix 20199b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 2020efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 2021c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 2022efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 20239b94acceSBarry Smith 20249b94acceSBarry Smith Calling sequence of func: 20258d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 20269b94acceSBarry Smith 2027c7afd0dbSLois Curfman McInnes + x - input vector 20289b94acceSBarry Smith . A - Jacobian matrix 20299b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 2030ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 20312b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 2032c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 20339b94acceSBarry Smith 20349b94acceSBarry Smith Notes: 203594b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 20362cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 2037ac21db08SLois Curfman McInnes 2038ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 20399b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 20409b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 20419b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 20429b94acceSBarry Smith throughout the global iterations. 20439b94acceSBarry Smith 204416913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 204516913363SBarry Smith each matrix. 204616913363SBarry Smith 2047a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 2048a8a26c1eSJed Brown must be a MatFDColoring. 2049a8a26c1eSJed Brown 2050c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2051c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2052c3cc8fd1SJed Brown 205336851e7fSLois Curfman McInnes Level: beginner 205436851e7fSLois Curfman McInnes 20559b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 20569b94acceSBarry Smith 20573ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 20589b94acceSBarry Smith @*/ 20597087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 20609b94acceSBarry Smith { 2061dfbe8321SBarry Smith PetscErrorCode ierr; 20626cab3a1bSJed Brown DM dm; 20633a7fca6bSBarry Smith 20643a40ed3dSBarry Smith PetscFunctionBegin; 20650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 20660700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 20670700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 2068c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 206906975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 20706cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 20716cab3a1bSJed Brown ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr); 20723a7fca6bSBarry Smith if (A) { 20737dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 20746bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 20759b94acceSBarry Smith snes->jacobian = A; 20763a7fca6bSBarry Smith } 20773a7fca6bSBarry Smith if (B) { 20787dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 20796bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 20809b94acceSBarry Smith snes->jacobian_pre = B; 20813a7fca6bSBarry Smith } 20823a40ed3dSBarry Smith PetscFunctionReturn(0); 20839b94acceSBarry Smith } 208462fef451SLois Curfman McInnes 20854a2ae208SSatish Balay #undef __FUNCT__ 20864a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 2087c2aafc4cSSatish Balay /*@C 2088b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2089b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2090b4fd4287SBarry Smith 2091c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2092c7afd0dbSLois Curfman McInnes 2093b4fd4287SBarry Smith Input Parameter: 2094b4fd4287SBarry Smith . snes - the nonlinear solver context 2095b4fd4287SBarry Smith 2096b4fd4287SBarry Smith Output Parameters: 2097c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 2098b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 209970e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 210070e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 2101fee21e36SBarry Smith 210236851e7fSLois Curfman McInnes Level: advanced 210336851e7fSLois Curfman McInnes 2104b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 2105b4fd4287SBarry Smith @*/ 21067087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 2107b4fd4287SBarry Smith { 21086cab3a1bSJed Brown PetscErrorCode ierr; 21096cab3a1bSJed Brown DM dm; 21106cab3a1bSJed Brown SNESDM sdm; 21116cab3a1bSJed Brown 21123a40ed3dSBarry Smith PetscFunctionBegin; 21130700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2114b4fd4287SBarry Smith if (A) *A = snes->jacobian; 2115b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 21166cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 21176cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 21186cab3a1bSJed Brown if (func) *func = sdm->computejacobian; 21196cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 21203a40ed3dSBarry Smith PetscFunctionReturn(0); 2121b4fd4287SBarry Smith } 2122b4fd4287SBarry Smith 21239b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 21249b94acceSBarry Smith 21254a2ae208SSatish Balay #undef __FUNCT__ 21264a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 21279b94acceSBarry Smith /*@ 21289b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2129272ac6f2SLois Curfman McInnes of a nonlinear solver. 21309b94acceSBarry Smith 2131fee21e36SBarry Smith Collective on SNES 2132fee21e36SBarry Smith 2133c7afd0dbSLois Curfman McInnes Input Parameters: 213470e92668SMatthew Knepley . snes - the SNES context 2135c7afd0dbSLois Curfman McInnes 2136272ac6f2SLois Curfman McInnes Notes: 2137272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2138272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2139272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2140272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2141272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2142272ac6f2SLois Curfman McInnes 214336851e7fSLois Curfman McInnes Level: advanced 214436851e7fSLois Curfman McInnes 21459b94acceSBarry Smith .keywords: SNES, nonlinear, setup 21469b94acceSBarry Smith 21479b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 21489b94acceSBarry Smith @*/ 21497087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 21509b94acceSBarry Smith { 2151dfbe8321SBarry Smith PetscErrorCode ierr; 21526cab3a1bSJed Brown DM dm; 21536cab3a1bSJed Brown SNESDM sdm; 21543a40ed3dSBarry Smith 21553a40ed3dSBarry Smith PetscFunctionBegin; 21560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 21574dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 21589b94acceSBarry Smith 21597adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 216085385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 216185385478SLisandro Dalcin } 216285385478SLisandro Dalcin 2163a63bb30eSJed Brown ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 216417186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 216558c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 216658c9b817SLisandro Dalcin 216758c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 216858c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 216958c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 217058c9b817SLisandro Dalcin } 217158c9b817SLisandro Dalcin 21726cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 21736cab3a1bSJed Brown ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */ 21746cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 21756cab3a1bSJed Brown if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc"); 21766cab3a1bSJed Brown if (!snes->vec_func) { 21776cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2178214df951SJed Brown } 2179efd51863SBarry Smith 2180b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 2181b710008aSBarry Smith 2182f1c6b773SPeter Brune if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);} 21839e764e56SPeter Brune 2184d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 2185d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2186d25893d9SBarry Smith } 2187d25893d9SBarry Smith 2188410397dcSLisandro Dalcin if (snes->ops->setup) { 2189410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2190410397dcSLisandro Dalcin } 219158c9b817SLisandro Dalcin 21927aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 21933a40ed3dSBarry Smith PetscFunctionReturn(0); 21949b94acceSBarry Smith } 21959b94acceSBarry Smith 21964a2ae208SSatish Balay #undef __FUNCT__ 219737596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 219837596af1SLisandro Dalcin /*@ 219937596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 220037596af1SLisandro Dalcin 220137596af1SLisandro Dalcin Collective on SNES 220237596af1SLisandro Dalcin 220337596af1SLisandro Dalcin Input Parameter: 220437596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 220537596af1SLisandro Dalcin 2206d25893d9SBarry Smith Level: intermediate 2207d25893d9SBarry Smith 2208d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 220937596af1SLisandro Dalcin 221037596af1SLisandro Dalcin .keywords: SNES, destroy 221137596af1SLisandro Dalcin 221237596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 221337596af1SLisandro Dalcin @*/ 221437596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 221537596af1SLisandro Dalcin { 221637596af1SLisandro Dalcin PetscErrorCode ierr; 221737596af1SLisandro Dalcin 221837596af1SLisandro Dalcin PetscFunctionBegin; 221937596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2220d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2221d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2222d25893d9SBarry Smith snes->user = PETSC_NULL; 2223d25893d9SBarry Smith } 22248a23116dSBarry Smith if (snes->pc) { 22258a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 22268a23116dSBarry Smith } 22278a23116dSBarry Smith 222837596af1SLisandro Dalcin if (snes->ops->reset) { 222937596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 223037596af1SLisandro Dalcin } 22319e764e56SPeter Brune if (snes->ksp) { 22329e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 22339e764e56SPeter Brune } 22349e764e56SPeter Brune 22359e764e56SPeter Brune if (snes->linesearch) { 2236f1c6b773SPeter Brune ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 22379e764e56SPeter Brune } 22389e764e56SPeter Brune 22396bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 22406bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 22416bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 22426bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 22436bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 22446bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2245c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2246c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 224737596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 224837596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 224937596af1SLisandro Dalcin PetscFunctionReturn(0); 225037596af1SLisandro Dalcin } 225137596af1SLisandro Dalcin 225237596af1SLisandro Dalcin #undef __FUNCT__ 22534a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 225452baeb72SSatish Balay /*@ 22559b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 22569b94acceSBarry Smith with SNESCreate(). 22579b94acceSBarry Smith 2258c7afd0dbSLois Curfman McInnes Collective on SNES 2259c7afd0dbSLois Curfman McInnes 22609b94acceSBarry Smith Input Parameter: 22619b94acceSBarry Smith . snes - the SNES context 22629b94acceSBarry Smith 226336851e7fSLois Curfman McInnes Level: beginner 226436851e7fSLois Curfman McInnes 22659b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 22669b94acceSBarry Smith 226763a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 22689b94acceSBarry Smith @*/ 22696bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 22709b94acceSBarry Smith { 22716849ba73SBarry Smith PetscErrorCode ierr; 22723a40ed3dSBarry Smith 22733a40ed3dSBarry Smith PetscFunctionBegin; 22746bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 22756bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 22766bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2277d4bb536fSBarry Smith 22786bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 22798a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 22806b8b9a38SLisandro Dalcin 2281be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 22826bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 22836bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 22846d4c513bSLisandro Dalcin 22856bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 22866bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 2287f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 22886b8b9a38SLisandro Dalcin 22896bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 22906bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 22916bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 22926b8b9a38SLisandro Dalcin } 22936bf464f9SBarry Smith if ((*snes)->conv_malloc) { 22946bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 22956bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 229658c9b817SLisandro Dalcin } 22976bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2298a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 22993a40ed3dSBarry Smith PetscFunctionReturn(0); 23009b94acceSBarry Smith } 23019b94acceSBarry Smith 23029b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 23039b94acceSBarry Smith 23044a2ae208SSatish Balay #undef __FUNCT__ 2305a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2306a8054027SBarry Smith /*@ 2307a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2308a8054027SBarry Smith 23093f9fe445SBarry Smith Logically Collective on SNES 2310a8054027SBarry Smith 2311a8054027SBarry Smith Input Parameters: 2312a8054027SBarry Smith + snes - the SNES context 2313a8054027SBarry 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 23143b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2315a8054027SBarry Smith 2316a8054027SBarry Smith Options Database Keys: 2317a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2318a8054027SBarry Smith 2319a8054027SBarry Smith Notes: 2320a8054027SBarry Smith The default is 1 2321a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2322a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2323a8054027SBarry Smith 2324a8054027SBarry Smith Level: intermediate 2325a8054027SBarry Smith 2326a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2327a8054027SBarry Smith 2328e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2329a8054027SBarry Smith 2330a8054027SBarry Smith @*/ 23317087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2332a8054027SBarry Smith { 2333a8054027SBarry Smith PetscFunctionBegin; 23340700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2335e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2336e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2337c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2338a8054027SBarry Smith snes->lagpreconditioner = lag; 2339a8054027SBarry Smith PetscFunctionReturn(0); 2340a8054027SBarry Smith } 2341a8054027SBarry Smith 2342a8054027SBarry Smith #undef __FUNCT__ 2343efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2344efd51863SBarry Smith /*@ 2345efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2346efd51863SBarry Smith 2347efd51863SBarry Smith Logically Collective on SNES 2348efd51863SBarry Smith 2349efd51863SBarry Smith Input Parameters: 2350efd51863SBarry Smith + snes - the SNES context 2351efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2352efd51863SBarry Smith 2353efd51863SBarry Smith Options Database Keys: 2354efd51863SBarry Smith . -snes_grid_sequence <steps> 2355efd51863SBarry Smith 2356efd51863SBarry Smith Level: intermediate 2357efd51863SBarry Smith 2358c0df2a02SJed Brown Notes: 2359c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2360c0df2a02SJed Brown 2361efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2362efd51863SBarry Smith 2363efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2364efd51863SBarry Smith 2365efd51863SBarry Smith @*/ 2366efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2367efd51863SBarry Smith { 2368efd51863SBarry Smith PetscFunctionBegin; 2369efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2370efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2371efd51863SBarry Smith snes->gridsequence = steps; 2372efd51863SBarry Smith PetscFunctionReturn(0); 2373efd51863SBarry Smith } 2374efd51863SBarry Smith 2375efd51863SBarry Smith #undef __FUNCT__ 2376a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2377a8054027SBarry Smith /*@ 2378a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2379a8054027SBarry Smith 23803f9fe445SBarry Smith Not Collective 2381a8054027SBarry Smith 2382a8054027SBarry Smith Input Parameter: 2383a8054027SBarry Smith . snes - the SNES context 2384a8054027SBarry Smith 2385a8054027SBarry Smith Output Parameter: 2386a8054027SBarry 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 23873b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2388a8054027SBarry Smith 2389a8054027SBarry Smith Options Database Keys: 2390a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2391a8054027SBarry Smith 2392a8054027SBarry Smith Notes: 2393a8054027SBarry Smith The default is 1 2394a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2395a8054027SBarry Smith 2396a8054027SBarry Smith Level: intermediate 2397a8054027SBarry Smith 2398a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2399a8054027SBarry Smith 2400a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2401a8054027SBarry Smith 2402a8054027SBarry Smith @*/ 24037087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2404a8054027SBarry Smith { 2405a8054027SBarry Smith PetscFunctionBegin; 24060700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2407a8054027SBarry Smith *lag = snes->lagpreconditioner; 2408a8054027SBarry Smith PetscFunctionReturn(0); 2409a8054027SBarry Smith } 2410a8054027SBarry Smith 2411a8054027SBarry Smith #undef __FUNCT__ 2412e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2413e35cf81dSBarry Smith /*@ 2414e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2415e35cf81dSBarry Smith often the preconditioner is rebuilt. 2416e35cf81dSBarry Smith 24173f9fe445SBarry Smith Logically Collective on SNES 2418e35cf81dSBarry Smith 2419e35cf81dSBarry Smith Input Parameters: 2420e35cf81dSBarry Smith + snes - the SNES context 2421e35cf81dSBarry 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 2422fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2423e35cf81dSBarry Smith 2424e35cf81dSBarry Smith Options Database Keys: 2425e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2426e35cf81dSBarry Smith 2427e35cf81dSBarry Smith Notes: 2428e35cf81dSBarry Smith The default is 1 2429e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2430fe3ffe1eSBarry 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 2431fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2432e35cf81dSBarry Smith 2433e35cf81dSBarry Smith Level: intermediate 2434e35cf81dSBarry Smith 2435e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2436e35cf81dSBarry Smith 2437e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2438e35cf81dSBarry Smith 2439e35cf81dSBarry Smith @*/ 24407087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2441e35cf81dSBarry Smith { 2442e35cf81dSBarry Smith PetscFunctionBegin; 24430700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2444e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2445e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2446c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2447e35cf81dSBarry Smith snes->lagjacobian = lag; 2448e35cf81dSBarry Smith PetscFunctionReturn(0); 2449e35cf81dSBarry Smith } 2450e35cf81dSBarry Smith 2451e35cf81dSBarry Smith #undef __FUNCT__ 2452e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2453e35cf81dSBarry Smith /*@ 2454e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2455e35cf81dSBarry Smith 24563f9fe445SBarry Smith Not Collective 2457e35cf81dSBarry Smith 2458e35cf81dSBarry Smith Input Parameter: 2459e35cf81dSBarry Smith . snes - the SNES context 2460e35cf81dSBarry Smith 2461e35cf81dSBarry Smith Output Parameter: 2462e35cf81dSBarry 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 2463e35cf81dSBarry Smith the Jacobian is built etc. 2464e35cf81dSBarry Smith 2465e35cf81dSBarry Smith Options Database Keys: 2466e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2467e35cf81dSBarry Smith 2468e35cf81dSBarry Smith Notes: 2469e35cf81dSBarry Smith The default is 1 2470e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2471e35cf81dSBarry Smith 2472e35cf81dSBarry Smith Level: intermediate 2473e35cf81dSBarry Smith 2474e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2475e35cf81dSBarry Smith 2476e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2477e35cf81dSBarry Smith 2478e35cf81dSBarry Smith @*/ 24797087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2480e35cf81dSBarry Smith { 2481e35cf81dSBarry Smith PetscFunctionBegin; 24820700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2483e35cf81dSBarry Smith *lag = snes->lagjacobian; 2484e35cf81dSBarry Smith PetscFunctionReturn(0); 2485e35cf81dSBarry Smith } 2486e35cf81dSBarry Smith 2487e35cf81dSBarry Smith #undef __FUNCT__ 24884a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 24899b94acceSBarry Smith /*@ 2490d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 24919b94acceSBarry Smith 24923f9fe445SBarry Smith Logically Collective on SNES 2493c7afd0dbSLois Curfman McInnes 24949b94acceSBarry Smith Input Parameters: 2495c7afd0dbSLois Curfman McInnes + snes - the SNES context 249670441072SBarry Smith . abstol - absolute convergence tolerance 249733174efeSLois Curfman McInnes . rtol - relative convergence tolerance 249833174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 249933174efeSLois Curfman McInnes of the change in the solution between steps 250033174efeSLois Curfman McInnes . maxit - maximum number of iterations 2501c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2502fee21e36SBarry Smith 250333174efeSLois Curfman McInnes Options Database Keys: 250470441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2505c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2506c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2507c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2508c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 25099b94acceSBarry Smith 2510d7a720efSLois Curfman McInnes Notes: 25119b94acceSBarry Smith The default maximum number of iterations is 50. 25129b94acceSBarry Smith The default maximum number of function evaluations is 1000. 25139b94acceSBarry Smith 251436851e7fSLois Curfman McInnes Level: intermediate 251536851e7fSLois Curfman McInnes 251633174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 25179b94acceSBarry Smith 25182492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 25199b94acceSBarry Smith @*/ 25207087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 25219b94acceSBarry Smith { 25223a40ed3dSBarry Smith PetscFunctionBegin; 25230700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2524c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2525c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2526c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2527c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2528c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2529c5eb9154SBarry Smith 2530ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2531ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2532ab54825eSJed Brown snes->abstol = abstol; 2533ab54825eSJed Brown } 2534ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2535ab54825eSJed 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); 2536ab54825eSJed Brown snes->rtol = rtol; 2537ab54825eSJed Brown } 2538ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2539ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2540*c60f73f4SPeter Brune snes->stol = stol; 2541ab54825eSJed Brown } 2542ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2543ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2544ab54825eSJed Brown snes->max_its = maxit; 2545ab54825eSJed Brown } 2546ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2547ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2548ab54825eSJed Brown snes->max_funcs = maxf; 2549ab54825eSJed Brown } 25503a40ed3dSBarry Smith PetscFunctionReturn(0); 25519b94acceSBarry Smith } 25529b94acceSBarry Smith 25534a2ae208SSatish Balay #undef __FUNCT__ 25544a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 25559b94acceSBarry Smith /*@ 255633174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 255733174efeSLois Curfman McInnes 2558c7afd0dbSLois Curfman McInnes Not Collective 2559c7afd0dbSLois Curfman McInnes 256033174efeSLois Curfman McInnes Input Parameters: 2561c7afd0dbSLois Curfman McInnes + snes - the SNES context 256285385478SLisandro Dalcin . atol - absolute convergence tolerance 256333174efeSLois Curfman McInnes . rtol - relative convergence tolerance 256433174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 256533174efeSLois Curfman McInnes of the change in the solution between steps 256633174efeSLois Curfman McInnes . maxit - maximum number of iterations 2567c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2568fee21e36SBarry Smith 256933174efeSLois Curfman McInnes Notes: 257033174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 257133174efeSLois Curfman McInnes 257236851e7fSLois Curfman McInnes Level: intermediate 257336851e7fSLois Curfman McInnes 257433174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 257533174efeSLois Curfman McInnes 257633174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 257733174efeSLois Curfman McInnes @*/ 25787087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 257933174efeSLois Curfman McInnes { 25803a40ed3dSBarry Smith PetscFunctionBegin; 25810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 258285385478SLisandro Dalcin if (atol) *atol = snes->abstol; 258333174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 2584*c60f73f4SPeter Brune if (stol) *stol = snes->stol; 258533174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 258633174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 25873a40ed3dSBarry Smith PetscFunctionReturn(0); 258833174efeSLois Curfman McInnes } 258933174efeSLois Curfman McInnes 25904a2ae208SSatish Balay #undef __FUNCT__ 25914a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 259233174efeSLois Curfman McInnes /*@ 25939b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 25949b94acceSBarry Smith 25953f9fe445SBarry Smith Logically Collective on SNES 2596fee21e36SBarry Smith 2597c7afd0dbSLois Curfman McInnes Input Parameters: 2598c7afd0dbSLois Curfman McInnes + snes - the SNES context 2599c7afd0dbSLois Curfman McInnes - tol - tolerance 2600c7afd0dbSLois Curfman McInnes 26019b94acceSBarry Smith Options Database Key: 2602c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 26039b94acceSBarry Smith 260436851e7fSLois Curfman McInnes Level: intermediate 260536851e7fSLois Curfman McInnes 26069b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 26079b94acceSBarry Smith 26082492ecdbSBarry Smith .seealso: SNESSetTolerances() 26099b94acceSBarry Smith @*/ 26107087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 26119b94acceSBarry Smith { 26123a40ed3dSBarry Smith PetscFunctionBegin; 26130700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2614c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 26159b94acceSBarry Smith snes->deltatol = tol; 26163a40ed3dSBarry Smith PetscFunctionReturn(0); 26179b94acceSBarry Smith } 26189b94acceSBarry Smith 2619df9fa365SBarry Smith /* 2620df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2621df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2622df9fa365SBarry Smith macros instead of functions 2623df9fa365SBarry Smith */ 26244a2ae208SSatish Balay #undef __FUNCT__ 2625a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 26267087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2627ce1608b8SBarry Smith { 2628dfbe8321SBarry Smith PetscErrorCode ierr; 2629ce1608b8SBarry Smith 2630ce1608b8SBarry Smith PetscFunctionBegin; 26310700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2632a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2633ce1608b8SBarry Smith PetscFunctionReturn(0); 2634ce1608b8SBarry Smith } 2635ce1608b8SBarry Smith 26364a2ae208SSatish Balay #undef __FUNCT__ 2637a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 26387087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2639df9fa365SBarry Smith { 2640dfbe8321SBarry Smith PetscErrorCode ierr; 2641df9fa365SBarry Smith 2642df9fa365SBarry Smith PetscFunctionBegin; 2643a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2644df9fa365SBarry Smith PetscFunctionReturn(0); 2645df9fa365SBarry Smith } 2646df9fa365SBarry Smith 26474a2ae208SSatish Balay #undef __FUNCT__ 2648a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 26496bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2650df9fa365SBarry Smith { 2651dfbe8321SBarry Smith PetscErrorCode ierr; 2652df9fa365SBarry Smith 2653df9fa365SBarry Smith PetscFunctionBegin; 2654a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2655df9fa365SBarry Smith PetscFunctionReturn(0); 2656df9fa365SBarry Smith } 2657df9fa365SBarry Smith 26587087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2659b271bb04SBarry Smith #undef __FUNCT__ 2660b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 26617087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2662b271bb04SBarry Smith { 2663b271bb04SBarry Smith PetscDrawLG lg; 2664b271bb04SBarry Smith PetscErrorCode ierr; 2665b271bb04SBarry Smith PetscReal x,y,per; 2666b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2667b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2668b271bb04SBarry Smith PetscDraw draw; 2669b271bb04SBarry Smith PetscFunctionBegin; 2670b271bb04SBarry Smith if (!monctx) { 2671b271bb04SBarry Smith MPI_Comm comm; 2672b271bb04SBarry Smith 2673b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2674b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2675b271bb04SBarry Smith } 2676b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2677b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2678b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2679b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2680b271bb04SBarry Smith x = (PetscReal) n; 2681b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2682b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2683b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2684b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2685b271bb04SBarry Smith } 2686b271bb04SBarry Smith 2687b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2688b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2689b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2690b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2691b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2692b271bb04SBarry Smith x = (PetscReal) n; 2693b271bb04SBarry Smith y = 100.0*per; 2694b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2695b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2696b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2697b271bb04SBarry Smith } 2698b271bb04SBarry Smith 2699b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2700b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2701b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2702b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2703b271bb04SBarry Smith x = (PetscReal) n; 2704b271bb04SBarry Smith y = (prev - rnorm)/prev; 2705b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2706b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2707b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2708b271bb04SBarry Smith } 2709b271bb04SBarry Smith 2710b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2711b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2712b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2713b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2714b271bb04SBarry Smith x = (PetscReal) n; 2715b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2716b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2717b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2718b271bb04SBarry Smith } 2719b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2720b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2721b271bb04SBarry Smith } 2722b271bb04SBarry Smith prev = rnorm; 2723b271bb04SBarry Smith PetscFunctionReturn(0); 2724b271bb04SBarry Smith } 2725b271bb04SBarry Smith 2726b271bb04SBarry Smith #undef __FUNCT__ 2727b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 27287087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2729b271bb04SBarry Smith { 2730b271bb04SBarry Smith PetscErrorCode ierr; 2731b271bb04SBarry Smith 2732b271bb04SBarry Smith PetscFunctionBegin; 2733b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2734b271bb04SBarry Smith PetscFunctionReturn(0); 2735b271bb04SBarry Smith } 2736b271bb04SBarry Smith 2737b271bb04SBarry Smith #undef __FUNCT__ 2738b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 27396bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2740b271bb04SBarry Smith { 2741b271bb04SBarry Smith PetscErrorCode ierr; 2742b271bb04SBarry Smith 2743b271bb04SBarry Smith PetscFunctionBegin; 2744b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2745b271bb04SBarry Smith PetscFunctionReturn(0); 2746b271bb04SBarry Smith } 2747b271bb04SBarry Smith 27487a03ce2fSLisandro Dalcin #undef __FUNCT__ 27497a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 2750228d79bcSJed Brown /*@ 2751228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 2752228d79bcSJed Brown 2753228d79bcSJed Brown Collective on SNES 2754228d79bcSJed Brown 2755228d79bcSJed Brown Input Parameters: 2756228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 2757228d79bcSJed Brown . iter - iteration number 2758228d79bcSJed Brown - rnorm - relative norm of the residual 2759228d79bcSJed Brown 2760228d79bcSJed Brown Notes: 2761228d79bcSJed Brown This routine is called by the SNES implementations. 2762228d79bcSJed Brown It does not typically need to be called by the user. 2763228d79bcSJed Brown 2764228d79bcSJed Brown Level: developer 2765228d79bcSJed Brown 2766228d79bcSJed Brown .seealso: SNESMonitorSet() 2767228d79bcSJed Brown @*/ 27687a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 27697a03ce2fSLisandro Dalcin { 27707a03ce2fSLisandro Dalcin PetscErrorCode ierr; 27717a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 27727a03ce2fSLisandro Dalcin 27737a03ce2fSLisandro Dalcin PetscFunctionBegin; 27747a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 27757a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 27767a03ce2fSLisandro Dalcin } 27777a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 27787a03ce2fSLisandro Dalcin } 27797a03ce2fSLisandro Dalcin 27809b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 27819b94acceSBarry Smith 27824a2ae208SSatish Balay #undef __FUNCT__ 2783a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 27849b94acceSBarry Smith /*@C 2785a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 27869b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 27879b94acceSBarry Smith progress. 27889b94acceSBarry Smith 27893f9fe445SBarry Smith Logically Collective on SNES 2790fee21e36SBarry Smith 2791c7afd0dbSLois Curfman McInnes Input Parameters: 2792c7afd0dbSLois Curfman McInnes + snes - the SNES context 2793c7afd0dbSLois Curfman McInnes . func - monitoring routine 2794b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 2795e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 2796b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 2797b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 27989b94acceSBarry Smith 2799c7afd0dbSLois Curfman McInnes Calling sequence of func: 2800a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2801c7afd0dbSLois Curfman McInnes 2802c7afd0dbSLois Curfman McInnes + snes - the SNES context 2803c7afd0dbSLois Curfman McInnes . its - iteration number 2804c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 280540a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 28069b94acceSBarry Smith 28079665c990SLois Curfman McInnes Options Database Keys: 2808a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 2809a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 2810a6570f20SBarry Smith uses SNESMonitorLGCreate() 2811cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 2812c7afd0dbSLois Curfman McInnes been hardwired into a code by 2813a6570f20SBarry Smith calls to SNESMonitorSet(), but 2814c7afd0dbSLois Curfman McInnes does not cancel those set via 2815c7afd0dbSLois Curfman McInnes the options database. 28169665c990SLois Curfman McInnes 2817639f9d9dSBarry Smith Notes: 28186bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 2819a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 28206bc08f3fSLois Curfman McInnes order in which they were set. 2821639f9d9dSBarry Smith 2822025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 2823025f1a04SBarry Smith 282436851e7fSLois Curfman McInnes Level: intermediate 282536851e7fSLois Curfman McInnes 28269b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 28279b94acceSBarry Smith 2828a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 28299b94acceSBarry Smith @*/ 2830c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 28319b94acceSBarry Smith { 2832b90d0a6eSBarry Smith PetscInt i; 2833649052a6SBarry Smith PetscErrorCode ierr; 2834b90d0a6eSBarry Smith 28353a40ed3dSBarry Smith PetscFunctionBegin; 28360700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 283717186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2838b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 2839649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 2840649052a6SBarry Smith if (monitordestroy) { 2841c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 2842649052a6SBarry Smith } 2843b90d0a6eSBarry Smith PetscFunctionReturn(0); 2844b90d0a6eSBarry Smith } 2845b90d0a6eSBarry Smith } 2846b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 2847b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 2848639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 28493a40ed3dSBarry Smith PetscFunctionReturn(0); 28509b94acceSBarry Smith } 28519b94acceSBarry Smith 28524a2ae208SSatish Balay #undef __FUNCT__ 2853a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 28545cd90555SBarry Smith /*@C 2855a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 28565cd90555SBarry Smith 28573f9fe445SBarry Smith Logically Collective on SNES 2858c7afd0dbSLois Curfman McInnes 28595cd90555SBarry Smith Input Parameters: 28605cd90555SBarry Smith . snes - the SNES context 28615cd90555SBarry Smith 28621a480d89SAdministrator Options Database Key: 2863a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 2864a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 2865c7afd0dbSLois Curfman McInnes set via the options database 28665cd90555SBarry Smith 28675cd90555SBarry Smith Notes: 28685cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 28695cd90555SBarry Smith 287036851e7fSLois Curfman McInnes Level: intermediate 287136851e7fSLois Curfman McInnes 28725cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 28735cd90555SBarry Smith 2874a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 28755cd90555SBarry Smith @*/ 28767087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 28775cd90555SBarry Smith { 2878d952e501SBarry Smith PetscErrorCode ierr; 2879d952e501SBarry Smith PetscInt i; 2880d952e501SBarry Smith 28815cd90555SBarry Smith PetscFunctionBegin; 28820700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2883d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 2884d952e501SBarry Smith if (snes->monitordestroy[i]) { 28853c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 2886d952e501SBarry Smith } 2887d952e501SBarry Smith } 28885cd90555SBarry Smith snes->numbermonitors = 0; 28895cd90555SBarry Smith PetscFunctionReturn(0); 28905cd90555SBarry Smith } 28915cd90555SBarry Smith 28924a2ae208SSatish Balay #undef __FUNCT__ 28934a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 28949b94acceSBarry Smith /*@C 28959b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 28969b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 28979b94acceSBarry Smith 28983f9fe445SBarry Smith Logically Collective on SNES 2899fee21e36SBarry Smith 2900c7afd0dbSLois Curfman McInnes Input Parameters: 2901c7afd0dbSLois Curfman McInnes + snes - the SNES context 2902c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 29037f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 29047f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 29059b94acceSBarry Smith 2906c7afd0dbSLois Curfman McInnes Calling sequence of func: 290706ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 2908c7afd0dbSLois Curfman McInnes 2909c7afd0dbSLois Curfman McInnes + snes - the SNES context 291006ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 2911c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 2912184914b5SBarry Smith . reason - reason for convergence/divergence 2913c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 29144b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 29154b27c08aSLois Curfman McInnes - f - 2-norm of function 29169b94acceSBarry Smith 291736851e7fSLois Curfman McInnes Level: advanced 291836851e7fSLois Curfman McInnes 29199b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 29209b94acceSBarry Smith 292185385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 29229b94acceSBarry Smith @*/ 29237087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 29249b94acceSBarry Smith { 29257f7931b9SBarry Smith PetscErrorCode ierr; 29267f7931b9SBarry Smith 29273a40ed3dSBarry Smith PetscFunctionBegin; 29280700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 292985385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 29307f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 29317f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 29327f7931b9SBarry Smith } 293385385478SLisandro Dalcin snes->ops->converged = func; 29347f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 293585385478SLisandro Dalcin snes->cnvP = cctx; 29363a40ed3dSBarry Smith PetscFunctionReturn(0); 29379b94acceSBarry Smith } 29389b94acceSBarry Smith 29394a2ae208SSatish Balay #undef __FUNCT__ 29404a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 294152baeb72SSatish Balay /*@ 2942184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 2943184914b5SBarry Smith 2944184914b5SBarry Smith Not Collective 2945184914b5SBarry Smith 2946184914b5SBarry Smith Input Parameter: 2947184914b5SBarry Smith . snes - the SNES context 2948184914b5SBarry Smith 2949184914b5SBarry Smith Output Parameter: 29504d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 2951184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 2952184914b5SBarry Smith 2953184914b5SBarry Smith Level: intermediate 2954184914b5SBarry Smith 2955184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 2956184914b5SBarry Smith 2957184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 2958184914b5SBarry Smith 295985385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 2960184914b5SBarry Smith @*/ 29617087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 2962184914b5SBarry Smith { 2963184914b5SBarry Smith PetscFunctionBegin; 29640700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 29654482741eSBarry Smith PetscValidPointer(reason,2); 2966184914b5SBarry Smith *reason = snes->reason; 2967184914b5SBarry Smith PetscFunctionReturn(0); 2968184914b5SBarry Smith } 2969184914b5SBarry Smith 29704a2ae208SSatish Balay #undef __FUNCT__ 29714a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 2972c9005455SLois Curfman McInnes /*@ 2973c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 2974c9005455SLois Curfman McInnes 29753f9fe445SBarry Smith Logically Collective on SNES 2976fee21e36SBarry Smith 2977c7afd0dbSLois Curfman McInnes Input Parameters: 2978c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 29798c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 2980cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 2981758f92a0SBarry Smith . na - size of a and its 298264731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 2983758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 2984c7afd0dbSLois Curfman McInnes 2985308dcc3eSBarry Smith Notes: 2986308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 2987308dcc3eSBarry Smith default array of length 10000 is allocated. 2988308dcc3eSBarry Smith 2989c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 2990c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 2991c9005455SLois Curfman McInnes during the section of code that is being timed. 2992c9005455SLois Curfman McInnes 299336851e7fSLois Curfman McInnes Level: intermediate 299436851e7fSLois Curfman McInnes 2995c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 2996758f92a0SBarry Smith 299708405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 2998758f92a0SBarry Smith 2999c9005455SLois Curfman McInnes @*/ 30007087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 3001c9005455SLois Curfman McInnes { 3002308dcc3eSBarry Smith PetscErrorCode ierr; 3003308dcc3eSBarry Smith 30043a40ed3dSBarry Smith PetscFunctionBegin; 30050700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 30064482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 3007a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 3008308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 3009308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 3010308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 3011308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 3012308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 3013308dcc3eSBarry Smith } 3014c9005455SLois Curfman McInnes snes->conv_hist = a; 3015758f92a0SBarry Smith snes->conv_hist_its = its; 3016758f92a0SBarry Smith snes->conv_hist_max = na; 3017a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 3018758f92a0SBarry Smith snes->conv_hist_reset = reset; 3019758f92a0SBarry Smith PetscFunctionReturn(0); 3020758f92a0SBarry Smith } 3021758f92a0SBarry Smith 3022308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3023c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 3024c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 3025308dcc3eSBarry Smith EXTERN_C_BEGIN 3026308dcc3eSBarry Smith #undef __FUNCT__ 3027308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 3028308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3029308dcc3eSBarry Smith { 3030308dcc3eSBarry Smith mxArray *mat; 3031308dcc3eSBarry Smith PetscInt i; 3032308dcc3eSBarry Smith PetscReal *ar; 3033308dcc3eSBarry Smith 3034308dcc3eSBarry Smith PetscFunctionBegin; 3035308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3036308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3037308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 3038308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 3039308dcc3eSBarry Smith } 3040308dcc3eSBarry Smith PetscFunctionReturn(mat); 3041308dcc3eSBarry Smith } 3042308dcc3eSBarry Smith EXTERN_C_END 3043308dcc3eSBarry Smith #endif 3044308dcc3eSBarry Smith 3045308dcc3eSBarry Smith 30464a2ae208SSatish Balay #undef __FUNCT__ 30474a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 30480c4c9dddSBarry Smith /*@C 3049758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3050758f92a0SBarry Smith 30513f9fe445SBarry Smith Not Collective 3052758f92a0SBarry Smith 3053758f92a0SBarry Smith Input Parameter: 3054758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3055758f92a0SBarry Smith 3056758f92a0SBarry Smith Output Parameters: 3057758f92a0SBarry Smith . a - array to hold history 3058758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3059758f92a0SBarry Smith negative if not converged) for each solve. 3060758f92a0SBarry Smith - na - size of a and its 3061758f92a0SBarry Smith 3062758f92a0SBarry Smith Notes: 3063758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3064758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3065758f92a0SBarry Smith 3066758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3067758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3068758f92a0SBarry Smith during the section of code that is being timed. 3069758f92a0SBarry Smith 3070758f92a0SBarry Smith Level: intermediate 3071758f92a0SBarry Smith 3072758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3073758f92a0SBarry Smith 3074758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3075758f92a0SBarry Smith 3076758f92a0SBarry Smith @*/ 30777087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3078758f92a0SBarry Smith { 3079758f92a0SBarry Smith PetscFunctionBegin; 30800700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3081758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3082758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3083758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 30843a40ed3dSBarry Smith PetscFunctionReturn(0); 3085c9005455SLois Curfman McInnes } 3086c9005455SLois Curfman McInnes 3087e74ef692SMatthew Knepley #undef __FUNCT__ 3088e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 3089ac226902SBarry Smith /*@C 309076b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3091eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 30927e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 309376b2cf59SMatthew Knepley 30943f9fe445SBarry Smith Logically Collective on SNES 309576b2cf59SMatthew Knepley 309676b2cf59SMatthew Knepley Input Parameters: 309776b2cf59SMatthew Knepley . snes - The nonlinear solver context 309876b2cf59SMatthew Knepley . func - The function 309976b2cf59SMatthew Knepley 310076b2cf59SMatthew Knepley Calling sequence of func: 3101b5d30489SBarry Smith . func (SNES snes, PetscInt step); 310276b2cf59SMatthew Knepley 310376b2cf59SMatthew Knepley . step - The current step of the iteration 310476b2cf59SMatthew Knepley 3105fe97e370SBarry Smith Level: advanced 3106fe97e370SBarry Smith 3107fe97e370SBarry 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() 3108fe97e370SBarry Smith This is not used by most users. 310976b2cf59SMatthew Knepley 311076b2cf59SMatthew Knepley .keywords: SNES, update 3111b5d30489SBarry Smith 311285385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 311376b2cf59SMatthew Knepley @*/ 31147087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 311576b2cf59SMatthew Knepley { 311676b2cf59SMatthew Knepley PetscFunctionBegin; 31170700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3118e7788613SBarry Smith snes->ops->update = func; 311976b2cf59SMatthew Knepley PetscFunctionReturn(0); 312076b2cf59SMatthew Knepley } 312176b2cf59SMatthew Knepley 3122e74ef692SMatthew Knepley #undef __FUNCT__ 3123e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 312476b2cf59SMatthew Knepley /*@ 312576b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 312676b2cf59SMatthew Knepley 312776b2cf59SMatthew Knepley Not collective 312876b2cf59SMatthew Knepley 312976b2cf59SMatthew Knepley Input Parameters: 313076b2cf59SMatthew Knepley . snes - The nonlinear solver context 313176b2cf59SMatthew Knepley . step - The current step of the iteration 313276b2cf59SMatthew Knepley 3133205452f4SMatthew Knepley Level: intermediate 3134205452f4SMatthew Knepley 313576b2cf59SMatthew Knepley .keywords: SNES, update 3136a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 313776b2cf59SMatthew Knepley @*/ 31387087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 313976b2cf59SMatthew Knepley { 314076b2cf59SMatthew Knepley PetscFunctionBegin; 314176b2cf59SMatthew Knepley PetscFunctionReturn(0); 314276b2cf59SMatthew Knepley } 314376b2cf59SMatthew Knepley 31444a2ae208SSatish Balay #undef __FUNCT__ 31454a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 31469b94acceSBarry Smith /* 31479b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 31489b94acceSBarry Smith positive parameter delta. 31499b94acceSBarry Smith 31509b94acceSBarry Smith Input Parameters: 3151c7afd0dbSLois Curfman McInnes + snes - the SNES context 31529b94acceSBarry Smith . y - approximate solution of linear system 31539b94acceSBarry Smith . fnorm - 2-norm of current function 3154c7afd0dbSLois Curfman McInnes - delta - trust region size 31559b94acceSBarry Smith 31569b94acceSBarry Smith Output Parameters: 3157c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 31589b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 31599b94acceSBarry Smith region, and exceeds zero otherwise. 3160c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 31619b94acceSBarry Smith 31629b94acceSBarry Smith Note: 31634b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 31649b94acceSBarry Smith is set to be the maximum allowable step size. 31659b94acceSBarry Smith 31669b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 31679b94acceSBarry Smith */ 3168dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 31699b94acceSBarry Smith { 3170064f8208SBarry Smith PetscReal nrm; 3171ea709b57SSatish Balay PetscScalar cnorm; 3172dfbe8321SBarry Smith PetscErrorCode ierr; 31733a40ed3dSBarry Smith 31743a40ed3dSBarry Smith PetscFunctionBegin; 31750700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31760700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3177c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3178184914b5SBarry Smith 3179064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3180064f8208SBarry Smith if (nrm > *delta) { 3181064f8208SBarry Smith nrm = *delta/nrm; 3182064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3183064f8208SBarry Smith cnorm = nrm; 31842dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 31859b94acceSBarry Smith *ynorm = *delta; 31869b94acceSBarry Smith } else { 31879b94acceSBarry Smith *gpnorm = 0.0; 3188064f8208SBarry Smith *ynorm = nrm; 31899b94acceSBarry Smith } 31903a40ed3dSBarry Smith PetscFunctionReturn(0); 31919b94acceSBarry Smith } 31929b94acceSBarry Smith 31934a2ae208SSatish Balay #undef __FUNCT__ 31944a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 31956ce558aeSBarry Smith /*@C 3196f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3197f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 31989b94acceSBarry Smith 3199c7afd0dbSLois Curfman McInnes Collective on SNES 3200c7afd0dbSLois Curfman McInnes 3201b2002411SLois Curfman McInnes Input Parameters: 3202c7afd0dbSLois Curfman McInnes + snes - the SNES context 32033cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 320485385478SLisandro Dalcin - x - the solution vector. 32059b94acceSBarry Smith 3206b2002411SLois Curfman McInnes Notes: 32078ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 32088ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 32098ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 32108ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 32118ddd3da0SLois Curfman McInnes 321236851e7fSLois Curfman McInnes Level: beginner 321336851e7fSLois Curfman McInnes 32149b94acceSBarry Smith .keywords: SNES, nonlinear, solve 32159b94acceSBarry Smith 3216c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 32179b94acceSBarry Smith @*/ 32187087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 32199b94acceSBarry Smith { 3220dfbe8321SBarry Smith PetscErrorCode ierr; 3221ace3abfcSBarry Smith PetscBool flg; 3222eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 3223eabae89aSBarry Smith PetscViewer viewer; 3224efd51863SBarry Smith PetscInt grid; 3225a69afd8bSBarry Smith Vec xcreated = PETSC_NULL; 3226caa4e7f2SJed Brown DM dm; 3227052efed2SBarry Smith 32283a40ed3dSBarry Smith PetscFunctionBegin; 32290700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3230a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3231a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 32320700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 323385385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 323485385478SLisandro Dalcin 3235caa4e7f2SJed Brown if (!x) { 3236caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3237caa4e7f2SJed Brown ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 3238a69afd8bSBarry Smith x = xcreated; 3239a69afd8bSBarry Smith } 3240a69afd8bSBarry Smith 3241a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3242efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3243efd51863SBarry Smith 324485385478SLisandro Dalcin /* set solution vector */ 3245efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 32466bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 324785385478SLisandro Dalcin snes->vec_sol = x; 3248caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3249caa4e7f2SJed Brown ierr = DMSNESSetSolution(snes->dm,snes->vec_sol);CHKERRQ(ierr); /* Post the solution vector so that it can be restricted to coarse levels for KSP */ 3250caa4e7f2SJed Brown 3251caa4e7f2SJed Brown /* set affine vector if provided */ 325285385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 32536bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 325485385478SLisandro Dalcin snes->vec_rhs = b; 325585385478SLisandro Dalcin 325670e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 32573f149594SLisandro Dalcin 32587eee914bSBarry Smith if (!grid) { 32597eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3260d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3261dd568438SSatish Balay } else if (snes->dm) { 3262dd568438SSatish Balay PetscBool ig; 3263dd568438SSatish Balay ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr); 3264dd568438SSatish Balay if (ig) { 32657eee914bSBarry Smith ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr); 32667eee914bSBarry Smith } 3267d25893d9SBarry Smith } 3268dd568438SSatish Balay } 3269d25893d9SBarry Smith 3270abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 327150ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3272d5e45103SBarry Smith 32733f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 32744936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 327585385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 32764936397dSBarry Smith if (snes->domainerror){ 32774936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 32784936397dSBarry Smith snes->domainerror = PETSC_FALSE; 32794936397dSBarry Smith } 328017186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 3281caa4e7f2SJed Brown ierr = DMSNESSetSolution(snes->dm,PETSC_NULL);CHKERRQ(ierr); /* Un-post solution because inner contexts are done using it */ 32823f149594SLisandro Dalcin 32837adad957SLisandro Dalcin ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 3284eabae89aSBarry Smith if (flg && !PetscPreLoadingOn) { 32857adad957SLisandro Dalcin ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 3286eabae89aSBarry Smith ierr = SNESView(snes,viewer);CHKERRQ(ierr); 32876bf464f9SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3288eabae89aSBarry Smith } 3289eabae89aSBarry Smith 329090d69ab7SBarry Smith flg = PETSC_FALSE; 3291acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3292da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 32935968eb51SBarry Smith if (snes->printreason) { 3294a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 32955968eb51SBarry Smith if (snes->reason > 0) { 3296c7e7b494SJed 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); 32975968eb51SBarry Smith } else { 3298c7e7b494SJed 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); 32995968eb51SBarry Smith } 3300a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 33015968eb51SBarry Smith } 33025968eb51SBarry Smith 33038501fc72SJed Brown flg = PETSC_FALSE; 33048501fc72SJed Brown ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 33058501fc72SJed Brown if (flg) { 33068501fc72SJed Brown PetscViewer viewer; 33078501fc72SJed Brown ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 33088501fc72SJed Brown ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 33098501fc72SJed Brown ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 33108501fc72SJed Brown ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 33118501fc72SJed Brown ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 33128501fc72SJed Brown } 33138501fc72SJed Brown 3314e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3315efd51863SBarry Smith if (grid < snes->gridsequence) { 3316efd51863SBarry Smith DM fine; 3317efd51863SBarry Smith Vec xnew; 3318efd51863SBarry Smith Mat interp; 3319efd51863SBarry Smith 3320efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3321e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3322efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3323efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3324efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3325efd51863SBarry Smith x = xnew; 3326efd51863SBarry Smith 3327efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3328efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3329efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3330a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3331efd51863SBarry Smith } 3332efd51863SBarry Smith } 3333a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 33343a40ed3dSBarry Smith PetscFunctionReturn(0); 33359b94acceSBarry Smith } 33369b94acceSBarry Smith 33379b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 33389b94acceSBarry Smith 33394a2ae208SSatish Balay #undef __FUNCT__ 33404a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 334182bf6240SBarry Smith /*@C 33424b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 33439b94acceSBarry Smith 3344fee21e36SBarry Smith Collective on SNES 3345fee21e36SBarry Smith 3346c7afd0dbSLois Curfman McInnes Input Parameters: 3347c7afd0dbSLois Curfman McInnes + snes - the SNES context 3348454a90a3SBarry Smith - type - a known method 3349c7afd0dbSLois Curfman McInnes 3350c7afd0dbSLois Curfman McInnes Options Database Key: 3351454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3352c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3353ae12b187SLois Curfman McInnes 33549b94acceSBarry Smith Notes: 3355e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 33564b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3357c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 33584b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3359c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 33609b94acceSBarry Smith 3361ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3362ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3363ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3364ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3365ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3366ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3367ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3368ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3369ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3370b0a32e0cSBarry Smith appropriate method. 337136851e7fSLois Curfman McInnes 337236851e7fSLois Curfman McInnes Level: intermediate 3373a703fe33SLois Curfman McInnes 3374454a90a3SBarry Smith .keywords: SNES, set, type 3375435da068SBarry Smith 3376435da068SBarry Smith .seealso: SNESType, SNESCreate() 3377435da068SBarry Smith 33789b94acceSBarry Smith @*/ 33797087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 33809b94acceSBarry Smith { 3381dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3382ace3abfcSBarry Smith PetscBool match; 33833a40ed3dSBarry Smith 33843a40ed3dSBarry Smith PetscFunctionBegin; 33850700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 33864482741eSBarry Smith PetscValidCharPointer(type,2); 338782bf6240SBarry Smith 33886831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 33890f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 339092ff6ae8SBarry Smith 33914b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3392e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 339375396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 3394b5c23020SJed Brown if (snes->ops->destroy) { 3395b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 3396b5c23020SJed Brown snes->ops->destroy = PETSC_NULL; 3397b5c23020SJed Brown } 339875396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 339975396ef9SLisandro Dalcin snes->ops->setup = 0; 340075396ef9SLisandro Dalcin snes->ops->solve = 0; 340175396ef9SLisandro Dalcin snes->ops->view = 0; 340275396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 340375396ef9SLisandro Dalcin snes->ops->destroy = 0; 340475396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 340575396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3406454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 340703bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 34089fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 34099fb22e1aSBarry Smith if (PetscAMSPublishAll) { 34109fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 34119fb22e1aSBarry Smith } 34129fb22e1aSBarry Smith #endif 34133a40ed3dSBarry Smith PetscFunctionReturn(0); 34149b94acceSBarry Smith } 34159b94acceSBarry Smith 3416a847f771SSatish Balay 34179b94acceSBarry Smith /* --------------------------------------------------------------------- */ 34184a2ae208SSatish Balay #undef __FUNCT__ 34194a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 342052baeb72SSatish Balay /*@ 34219b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3422f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 34239b94acceSBarry Smith 3424fee21e36SBarry Smith Not Collective 3425fee21e36SBarry Smith 342636851e7fSLois Curfman McInnes Level: advanced 342736851e7fSLois Curfman McInnes 34289b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 34299b94acceSBarry Smith 34309b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 34319b94acceSBarry Smith @*/ 34327087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 34339b94acceSBarry Smith { 3434dfbe8321SBarry Smith PetscErrorCode ierr; 343582bf6240SBarry Smith 34363a40ed3dSBarry Smith PetscFunctionBegin; 34371441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 34384c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 34393a40ed3dSBarry Smith PetscFunctionReturn(0); 34409b94acceSBarry Smith } 34419b94acceSBarry Smith 34424a2ae208SSatish Balay #undef __FUNCT__ 34434a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 34449b94acceSBarry Smith /*@C 34459a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 34469b94acceSBarry Smith 3447c7afd0dbSLois Curfman McInnes Not Collective 3448c7afd0dbSLois Curfman McInnes 34499b94acceSBarry Smith Input Parameter: 34504b0e389bSBarry Smith . snes - nonlinear solver context 34519b94acceSBarry Smith 34529b94acceSBarry Smith Output Parameter: 34533a7fca6bSBarry Smith . type - SNES method (a character string) 34549b94acceSBarry Smith 345536851e7fSLois Curfman McInnes Level: intermediate 345636851e7fSLois Curfman McInnes 3457454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 34589b94acceSBarry Smith @*/ 34597087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 34609b94acceSBarry Smith { 34613a40ed3dSBarry Smith PetscFunctionBegin; 34620700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34634482741eSBarry Smith PetscValidPointer(type,2); 34647adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 34653a40ed3dSBarry Smith PetscFunctionReturn(0); 34669b94acceSBarry Smith } 34679b94acceSBarry Smith 34684a2ae208SSatish Balay #undef __FUNCT__ 34694a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 347052baeb72SSatish Balay /*@ 34719b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3472c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 34739b94acceSBarry Smith 3474c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3475c7afd0dbSLois Curfman McInnes 34769b94acceSBarry Smith Input Parameter: 34779b94acceSBarry Smith . snes - the SNES context 34789b94acceSBarry Smith 34799b94acceSBarry Smith Output Parameter: 34809b94acceSBarry Smith . x - the solution 34819b94acceSBarry Smith 348270e92668SMatthew Knepley Level: intermediate 348336851e7fSLois Curfman McInnes 34849b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 34859b94acceSBarry Smith 348685385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 34879b94acceSBarry Smith @*/ 34887087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 34899b94acceSBarry Smith { 34903a40ed3dSBarry Smith PetscFunctionBegin; 34910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34924482741eSBarry Smith PetscValidPointer(x,2); 349385385478SLisandro Dalcin *x = snes->vec_sol; 349470e92668SMatthew Knepley PetscFunctionReturn(0); 349570e92668SMatthew Knepley } 349670e92668SMatthew Knepley 349770e92668SMatthew Knepley #undef __FUNCT__ 34984a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 349952baeb72SSatish Balay /*@ 35009b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 35019b94acceSBarry Smith stored. 35029b94acceSBarry Smith 3503c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3504c7afd0dbSLois Curfman McInnes 35059b94acceSBarry Smith Input Parameter: 35069b94acceSBarry Smith . snes - the SNES context 35079b94acceSBarry Smith 35089b94acceSBarry Smith Output Parameter: 35099b94acceSBarry Smith . x - the solution update 35109b94acceSBarry Smith 351136851e7fSLois Curfman McInnes Level: advanced 351236851e7fSLois Curfman McInnes 35139b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 35149b94acceSBarry Smith 351585385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 35169b94acceSBarry Smith @*/ 35177087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 35189b94acceSBarry Smith { 35193a40ed3dSBarry Smith PetscFunctionBegin; 35200700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35214482741eSBarry Smith PetscValidPointer(x,2); 352285385478SLisandro Dalcin *x = snes->vec_sol_update; 35233a40ed3dSBarry Smith PetscFunctionReturn(0); 35249b94acceSBarry Smith } 35259b94acceSBarry Smith 35264a2ae208SSatish Balay #undef __FUNCT__ 35274a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 35289b94acceSBarry Smith /*@C 35293638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 35309b94acceSBarry Smith 3531a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 3532c7afd0dbSLois Curfman McInnes 35339b94acceSBarry Smith Input Parameter: 35349b94acceSBarry Smith . snes - the SNES context 35359b94acceSBarry Smith 35369b94acceSBarry Smith Output Parameter: 35377bf4e008SBarry Smith + r - the function (or PETSC_NULL) 353870e92668SMatthew Knepley . func - the function (or PETSC_NULL) 353970e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 35409b94acceSBarry Smith 354136851e7fSLois Curfman McInnes Level: advanced 354236851e7fSLois Curfman McInnes 3543a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 35449b94acceSBarry Smith 35454b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 35469b94acceSBarry Smith @*/ 35477087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 35489b94acceSBarry Smith { 3549a63bb30eSJed Brown PetscErrorCode ierr; 35506cab3a1bSJed Brown DM dm; 3551a63bb30eSJed Brown 35523a40ed3dSBarry Smith PetscFunctionBegin; 35530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3554a63bb30eSJed Brown if (r) { 3555a63bb30eSJed Brown if (!snes->vec_func) { 3556a63bb30eSJed Brown if (snes->vec_rhs) { 3557a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 3558a63bb30eSJed Brown } else if (snes->vec_sol) { 3559a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 3560a63bb30eSJed Brown } else if (snes->dm) { 3561a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 3562a63bb30eSJed Brown } 3563a63bb30eSJed Brown } 3564a63bb30eSJed Brown *r = snes->vec_func; 3565a63bb30eSJed Brown } 35666cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 35676cab3a1bSJed Brown ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr); 35683a40ed3dSBarry Smith PetscFunctionReturn(0); 35699b94acceSBarry Smith } 35709b94acceSBarry Smith 3571c79ef259SPeter Brune /*@C 3572c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3573c79ef259SPeter Brune 3574c79ef259SPeter Brune Input Parameter: 3575c79ef259SPeter Brune . snes - the SNES context 3576c79ef259SPeter Brune 3577c79ef259SPeter Brune Output Parameter: 3578c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3579c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3580c79ef259SPeter Brune 3581c79ef259SPeter Brune Level: advanced 3582c79ef259SPeter Brune 3583c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3584c79ef259SPeter Brune 3585c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3586c79ef259SPeter Brune @*/ 3587c79ef259SPeter Brune 35884a2ae208SSatish Balay #undef __FUNCT__ 3589646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3590646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3591646217ecSPeter Brune { 35926cab3a1bSJed Brown PetscErrorCode ierr; 35936cab3a1bSJed Brown DM dm; 35946cab3a1bSJed Brown 3595646217ecSPeter Brune PetscFunctionBegin; 3596646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35976cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 35986cab3a1bSJed Brown ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr); 3599646217ecSPeter Brune PetscFunctionReturn(0); 3600646217ecSPeter Brune } 3601646217ecSPeter Brune 36024a2ae208SSatish Balay #undef __FUNCT__ 36034a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 36043c7409f5SSatish Balay /*@C 36053c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3606d850072dSLois Curfman McInnes SNES options in the database. 36073c7409f5SSatish Balay 36083f9fe445SBarry Smith Logically Collective on SNES 3609fee21e36SBarry Smith 3610c7afd0dbSLois Curfman McInnes Input Parameter: 3611c7afd0dbSLois Curfman McInnes + snes - the SNES context 3612c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3613c7afd0dbSLois Curfman McInnes 3614d850072dSLois Curfman McInnes Notes: 3615a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3616c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3617d850072dSLois Curfman McInnes 361836851e7fSLois Curfman McInnes Level: advanced 361936851e7fSLois Curfman McInnes 36203c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3621a86d99e1SLois Curfman McInnes 3622a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 36233c7409f5SSatish Balay @*/ 36247087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 36253c7409f5SSatish Balay { 3626dfbe8321SBarry Smith PetscErrorCode ierr; 36273c7409f5SSatish Balay 36283a40ed3dSBarry Smith PetscFunctionBegin; 36290700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3630639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 36311cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 363294b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 36333a40ed3dSBarry Smith PetscFunctionReturn(0); 36343c7409f5SSatish Balay } 36353c7409f5SSatish Balay 36364a2ae208SSatish Balay #undef __FUNCT__ 36374a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 36383c7409f5SSatish Balay /*@C 3639f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3640d850072dSLois Curfman McInnes SNES options in the database. 36413c7409f5SSatish Balay 36423f9fe445SBarry Smith Logically Collective on SNES 3643fee21e36SBarry Smith 3644c7afd0dbSLois Curfman McInnes Input Parameters: 3645c7afd0dbSLois Curfman McInnes + snes - the SNES context 3646c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3647c7afd0dbSLois Curfman McInnes 3648d850072dSLois Curfman McInnes Notes: 3649a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3650c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3651d850072dSLois Curfman McInnes 365236851e7fSLois Curfman McInnes Level: advanced 365336851e7fSLois Curfman McInnes 36543c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3655a86d99e1SLois Curfman McInnes 3656a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 36573c7409f5SSatish Balay @*/ 36587087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 36593c7409f5SSatish Balay { 3660dfbe8321SBarry Smith PetscErrorCode ierr; 36613c7409f5SSatish Balay 36623a40ed3dSBarry Smith PetscFunctionBegin; 36630700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3664639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 36651cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 366694b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 36673a40ed3dSBarry Smith PetscFunctionReturn(0); 36683c7409f5SSatish Balay } 36693c7409f5SSatish Balay 36704a2ae208SSatish Balay #undef __FUNCT__ 36714a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 36729ab63eb5SSatish Balay /*@C 36733c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 36743c7409f5SSatish Balay SNES options in the database. 36753c7409f5SSatish Balay 3676c7afd0dbSLois Curfman McInnes Not Collective 3677c7afd0dbSLois Curfman McInnes 36783c7409f5SSatish Balay Input Parameter: 36793c7409f5SSatish Balay . snes - the SNES context 36803c7409f5SSatish Balay 36813c7409f5SSatish Balay Output Parameter: 36823c7409f5SSatish Balay . prefix - pointer to the prefix string used 36833c7409f5SSatish Balay 36844ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 36859ab63eb5SSatish Balay sufficient length to hold the prefix. 36869ab63eb5SSatish Balay 368736851e7fSLois Curfman McInnes Level: advanced 368836851e7fSLois Curfman McInnes 36893c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 3690a86d99e1SLois Curfman McInnes 3691a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 36923c7409f5SSatish Balay @*/ 36937087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 36943c7409f5SSatish Balay { 3695dfbe8321SBarry Smith PetscErrorCode ierr; 36963c7409f5SSatish Balay 36973a40ed3dSBarry Smith PetscFunctionBegin; 36980700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3699639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 37003a40ed3dSBarry Smith PetscFunctionReturn(0); 37013c7409f5SSatish Balay } 37023c7409f5SSatish Balay 3703b2002411SLois Curfman McInnes 37044a2ae208SSatish Balay #undef __FUNCT__ 37054a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 37063cea93caSBarry Smith /*@C 37073cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 37083cea93caSBarry Smith 37097f6c08e0SMatthew Knepley Level: advanced 37103cea93caSBarry Smith @*/ 37117087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3712b2002411SLois Curfman McInnes { 3713e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3714dfbe8321SBarry Smith PetscErrorCode ierr; 3715b2002411SLois Curfman McInnes 3716b2002411SLois Curfman McInnes PetscFunctionBegin; 3717b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3718c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3719b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3720b2002411SLois Curfman McInnes } 3721da9b6338SBarry Smith 3722da9b6338SBarry Smith #undef __FUNCT__ 3723da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 37247087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3725da9b6338SBarry Smith { 3726dfbe8321SBarry Smith PetscErrorCode ierr; 372777431f27SBarry Smith PetscInt N,i,j; 3728da9b6338SBarry Smith Vec u,uh,fh; 3729da9b6338SBarry Smith PetscScalar value; 3730da9b6338SBarry Smith PetscReal norm; 3731da9b6338SBarry Smith 3732da9b6338SBarry Smith PetscFunctionBegin; 3733da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3734da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3735da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3736da9b6338SBarry Smith 3737da9b6338SBarry Smith /* currently only works for sequential */ 3738da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3739da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3740da9b6338SBarry Smith for (i=0; i<N; i++) { 3741da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 374277431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3743da9b6338SBarry Smith for (j=-10; j<11; j++) { 3744ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3745da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 37463ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3747da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 374877431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3749da9b6338SBarry Smith value = -value; 3750da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3751da9b6338SBarry Smith } 3752da9b6338SBarry Smith } 37536bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 37546bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 3755da9b6338SBarry Smith PetscFunctionReturn(0); 3756da9b6338SBarry Smith } 375771f87433Sdalcinl 375871f87433Sdalcinl #undef __FUNCT__ 3759fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 376071f87433Sdalcinl /*@ 3761fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 376271f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 376371f87433Sdalcinl Newton method. 376471f87433Sdalcinl 37653f9fe445SBarry Smith Logically Collective on SNES 376671f87433Sdalcinl 376771f87433Sdalcinl Input Parameters: 376871f87433Sdalcinl + snes - SNES context 376971f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 377071f87433Sdalcinl 377164ba62caSBarry Smith Options Database: 377264ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 377364ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 377464ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 377564ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 377664ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 377764ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 377864ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 377964ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 378064ba62caSBarry Smith 378171f87433Sdalcinl Notes: 378271f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 378371f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 378471f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 378571f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 378671f87433Sdalcinl solver. 378771f87433Sdalcinl 378871f87433Sdalcinl Level: advanced 378971f87433Sdalcinl 379071f87433Sdalcinl Reference: 379171f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 379271f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 379371f87433Sdalcinl 379471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 379571f87433Sdalcinl 3796fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 379771f87433Sdalcinl @*/ 37987087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 379971f87433Sdalcinl { 380071f87433Sdalcinl PetscFunctionBegin; 38010700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3802acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 380371f87433Sdalcinl snes->ksp_ewconv = flag; 380471f87433Sdalcinl PetscFunctionReturn(0); 380571f87433Sdalcinl } 380671f87433Sdalcinl 380771f87433Sdalcinl #undef __FUNCT__ 3808fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 380971f87433Sdalcinl /*@ 3810fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 381171f87433Sdalcinl for computing relative tolerance for linear solvers within an 381271f87433Sdalcinl inexact Newton method. 381371f87433Sdalcinl 381471f87433Sdalcinl Not Collective 381571f87433Sdalcinl 381671f87433Sdalcinl Input Parameter: 381771f87433Sdalcinl . snes - SNES context 381871f87433Sdalcinl 381971f87433Sdalcinl Output Parameter: 382071f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 382171f87433Sdalcinl 382271f87433Sdalcinl Notes: 382371f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 382471f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 382571f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 382671f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 382771f87433Sdalcinl solver. 382871f87433Sdalcinl 382971f87433Sdalcinl Level: advanced 383071f87433Sdalcinl 383171f87433Sdalcinl Reference: 383271f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 383371f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 383471f87433Sdalcinl 383571f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 383671f87433Sdalcinl 3837fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 383871f87433Sdalcinl @*/ 38397087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 384071f87433Sdalcinl { 384171f87433Sdalcinl PetscFunctionBegin; 38420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 384371f87433Sdalcinl PetscValidPointer(flag,2); 384471f87433Sdalcinl *flag = snes->ksp_ewconv; 384571f87433Sdalcinl PetscFunctionReturn(0); 384671f87433Sdalcinl } 384771f87433Sdalcinl 384871f87433Sdalcinl #undef __FUNCT__ 3849fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 385071f87433Sdalcinl /*@ 3851fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 385271f87433Sdalcinl convergence criteria for the linear solvers within an inexact 385371f87433Sdalcinl Newton method. 385471f87433Sdalcinl 38553f9fe445SBarry Smith Logically Collective on SNES 385671f87433Sdalcinl 385771f87433Sdalcinl Input Parameters: 385871f87433Sdalcinl + snes - SNES context 385971f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 386071f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 386171f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 386271f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 386371f87433Sdalcinl (0 <= gamma2 <= 1) 386471f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 386571f87433Sdalcinl . alpha2 - power for safeguard 386671f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 386771f87433Sdalcinl 386871f87433Sdalcinl Note: 386971f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 387071f87433Sdalcinl 387171f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 387271f87433Sdalcinl 387371f87433Sdalcinl Level: advanced 387471f87433Sdalcinl 387571f87433Sdalcinl Reference: 387671f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 387771f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 387871f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 387971f87433Sdalcinl 388071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 388171f87433Sdalcinl 3882fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 388371f87433Sdalcinl @*/ 38847087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 388571f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 388671f87433Sdalcinl { 3887fa9f3622SBarry Smith SNESKSPEW *kctx; 388871f87433Sdalcinl PetscFunctionBegin; 38890700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3890fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3891e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 3892c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 3893c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 3894c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 3895c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 3896c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 3897c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 3898c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 389971f87433Sdalcinl 390071f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 390171f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 390271f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 390371f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 390471f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 390571f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 390671f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 390771f87433Sdalcinl 390871f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 3909e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 391071f87433Sdalcinl } 391171f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 3912e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 391371f87433Sdalcinl } 391471f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 3915e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 391671f87433Sdalcinl } 391771f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 3918e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 391971f87433Sdalcinl } 392071f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 3921e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 392271f87433Sdalcinl } 392371f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 3924e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 392571f87433Sdalcinl } 392671f87433Sdalcinl PetscFunctionReturn(0); 392771f87433Sdalcinl } 392871f87433Sdalcinl 392971f87433Sdalcinl #undef __FUNCT__ 3930fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 393171f87433Sdalcinl /*@ 3932fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 393371f87433Sdalcinl convergence criteria for the linear solvers within an inexact 393471f87433Sdalcinl Newton method. 393571f87433Sdalcinl 393671f87433Sdalcinl Not Collective 393771f87433Sdalcinl 393871f87433Sdalcinl Input Parameters: 393971f87433Sdalcinl snes - SNES context 394071f87433Sdalcinl 394171f87433Sdalcinl Output Parameters: 394271f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 394371f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 394471f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 394571f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 394671f87433Sdalcinl (0 <= gamma2 <= 1) 394771f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 394871f87433Sdalcinl . alpha2 - power for safeguard 394971f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 395071f87433Sdalcinl 395171f87433Sdalcinl Level: advanced 395271f87433Sdalcinl 395371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 395471f87433Sdalcinl 3955fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 395671f87433Sdalcinl @*/ 39577087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 395871f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 395971f87433Sdalcinl { 3960fa9f3622SBarry Smith SNESKSPEW *kctx; 396171f87433Sdalcinl PetscFunctionBegin; 39620700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3963fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3964e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 396571f87433Sdalcinl if(version) *version = kctx->version; 396671f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 396771f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 396871f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 396971f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 397071f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 397171f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 397271f87433Sdalcinl PetscFunctionReturn(0); 397371f87433Sdalcinl } 397471f87433Sdalcinl 397571f87433Sdalcinl #undef __FUNCT__ 3976fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 3977fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 397871f87433Sdalcinl { 397971f87433Sdalcinl PetscErrorCode ierr; 3980fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 398171f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 398271f87433Sdalcinl 398371f87433Sdalcinl PetscFunctionBegin; 3984e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 398571f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 398671f87433Sdalcinl rtol = kctx->rtol_0; 398771f87433Sdalcinl } else { 398871f87433Sdalcinl if (kctx->version == 1) { 398971f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 399071f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 399171f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 399271f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 399371f87433Sdalcinl } else if (kctx->version == 2) { 399471f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 399571f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 399671f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 399771f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 399871f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 399971f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 400071f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 400171f87433Sdalcinl stol = PetscMax(rtol,stol); 400271f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 400371f87433Sdalcinl /* safeguard: avoid oversolving */ 400471f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 400571f87433Sdalcinl stol = PetscMax(rtol,stol); 400671f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 4007e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 400871f87433Sdalcinl } 400971f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 401071f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 401171f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 401271f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 401371f87433Sdalcinl PetscFunctionReturn(0); 401471f87433Sdalcinl } 401571f87433Sdalcinl 401671f87433Sdalcinl #undef __FUNCT__ 4017fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 4018fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 401971f87433Sdalcinl { 402071f87433Sdalcinl PetscErrorCode ierr; 4021fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 402271f87433Sdalcinl PCSide pcside; 402371f87433Sdalcinl Vec lres; 402471f87433Sdalcinl 402571f87433Sdalcinl PetscFunctionBegin; 4026e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 402771f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 402871f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 402971f87433Sdalcinl if (kctx->version == 1) { 4030b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 403171f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 403271f87433Sdalcinl /* KSP residual is true linear residual */ 403371f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 403471f87433Sdalcinl } else { 403571f87433Sdalcinl /* KSP residual is preconditioned residual */ 403671f87433Sdalcinl /* compute true linear residual norm */ 403771f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 403871f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 403971f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 404071f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 40416bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 404271f87433Sdalcinl } 404371f87433Sdalcinl } 404471f87433Sdalcinl PetscFunctionReturn(0); 404571f87433Sdalcinl } 404671f87433Sdalcinl 404771f87433Sdalcinl #undef __FUNCT__ 404871f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 404971f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 405071f87433Sdalcinl { 405171f87433Sdalcinl PetscErrorCode ierr; 405271f87433Sdalcinl 405371f87433Sdalcinl PetscFunctionBegin; 4054fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 405571f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 4056fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 405771f87433Sdalcinl PetscFunctionReturn(0); 405871f87433Sdalcinl } 40596c699258SBarry Smith 40606c699258SBarry Smith #undef __FUNCT__ 40616c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 40626c699258SBarry Smith /*@ 40636c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 40646c699258SBarry Smith 40653f9fe445SBarry Smith Logically Collective on SNES 40666c699258SBarry Smith 40676c699258SBarry Smith Input Parameters: 40686c699258SBarry Smith + snes - the preconditioner context 40696c699258SBarry Smith - dm - the dm 40706c699258SBarry Smith 40716c699258SBarry Smith Level: intermediate 40726c699258SBarry Smith 40736c699258SBarry Smith 40746c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 40756c699258SBarry Smith @*/ 40767087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 40776c699258SBarry Smith { 40786c699258SBarry Smith PetscErrorCode ierr; 4079345fed2cSBarry Smith KSP ksp; 40806cab3a1bSJed Brown SNESDM sdm; 40816c699258SBarry Smith 40826c699258SBarry Smith PetscFunctionBegin; 40830700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4084d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 40856cab3a1bSJed Brown if (snes->dm) { /* Move the SNESDM context over to the new DM unless the new DM already has one */ 40866cab3a1bSJed Brown PetscContainer oldcontainer,container; 40876cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 40886cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr); 40896cab3a1bSJed Brown if (oldcontainer && !container) { 40906cab3a1bSJed Brown ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr); 40916cab3a1bSJed Brown ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr); 40926cab3a1bSJed Brown if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */ 40936cab3a1bSJed Brown sdm->originaldm = dm; 40946cab3a1bSJed Brown } 40956cab3a1bSJed Brown } 40966bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 40976cab3a1bSJed Brown } 40986c699258SBarry Smith snes->dm = dm; 4099345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4100345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4101f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 41022c155ee1SBarry Smith if (snes->pc) { 41032c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 41042c155ee1SBarry Smith } 41056c699258SBarry Smith PetscFunctionReturn(0); 41066c699258SBarry Smith } 41076c699258SBarry Smith 41086c699258SBarry Smith #undef __FUNCT__ 41096c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 41106c699258SBarry Smith /*@ 41116c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 41126c699258SBarry Smith 41133f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 41146c699258SBarry Smith 41156c699258SBarry Smith Input Parameter: 41166c699258SBarry Smith . snes - the preconditioner context 41176c699258SBarry Smith 41186c699258SBarry Smith Output Parameter: 41196c699258SBarry Smith . dm - the dm 41206c699258SBarry Smith 41216c699258SBarry Smith Level: intermediate 41226c699258SBarry Smith 41236c699258SBarry Smith 41246c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 41256c699258SBarry Smith @*/ 41267087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 41276c699258SBarry Smith { 41286cab3a1bSJed Brown PetscErrorCode ierr; 41296cab3a1bSJed Brown 41306c699258SBarry Smith PetscFunctionBegin; 41310700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 41326cab3a1bSJed Brown if (!snes->dm) { 41336cab3a1bSJed Brown ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr); 41346cab3a1bSJed Brown } 41356c699258SBarry Smith *dm = snes->dm; 41366c699258SBarry Smith PetscFunctionReturn(0); 41376c699258SBarry Smith } 41380807856dSBarry Smith 413931823bd8SMatthew G Knepley #undef __FUNCT__ 414031823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 414131823bd8SMatthew G Knepley /*@ 4142fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 414331823bd8SMatthew G Knepley 414431823bd8SMatthew G Knepley Collective on SNES 414531823bd8SMatthew G Knepley 414631823bd8SMatthew G Knepley Input Parameters: 414731823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 414831823bd8SMatthew G Knepley - pc - the preconditioner object 414931823bd8SMatthew G Knepley 415031823bd8SMatthew G Knepley Notes: 415131823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 415231823bd8SMatthew G Knepley to configure it using the API). 415331823bd8SMatthew G Knepley 415431823bd8SMatthew G Knepley Level: developer 415531823bd8SMatthew G Knepley 415631823bd8SMatthew G Knepley .keywords: SNES, set, precondition 415731823bd8SMatthew G Knepley .seealso: SNESGetPC() 415831823bd8SMatthew G Knepley @*/ 415931823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 416031823bd8SMatthew G Knepley { 416131823bd8SMatthew G Knepley PetscErrorCode ierr; 416231823bd8SMatthew G Knepley 416331823bd8SMatthew G Knepley PetscFunctionBegin; 416431823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 416531823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 416631823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 416731823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4168bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 416931823bd8SMatthew G Knepley snes->pc = pc; 417031823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 417131823bd8SMatthew G Knepley PetscFunctionReturn(0); 417231823bd8SMatthew G Knepley } 417331823bd8SMatthew G Knepley 417431823bd8SMatthew G Knepley #undef __FUNCT__ 417531823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 417631823bd8SMatthew G Knepley /*@ 4177fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 417831823bd8SMatthew G Knepley 417931823bd8SMatthew G Knepley Not Collective 418031823bd8SMatthew G Knepley 418131823bd8SMatthew G Knepley Input Parameter: 418231823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 418331823bd8SMatthew G Knepley 418431823bd8SMatthew G Knepley Output Parameter: 418531823bd8SMatthew G Knepley . pc - preconditioner context 418631823bd8SMatthew G Knepley 418731823bd8SMatthew G Knepley Level: developer 418831823bd8SMatthew G Knepley 418931823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 419031823bd8SMatthew G Knepley .seealso: SNESSetPC() 419131823bd8SMatthew G Knepley @*/ 419231823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 419331823bd8SMatthew G Knepley { 419431823bd8SMatthew G Knepley PetscErrorCode ierr; 419531823bd8SMatthew G Knepley 419631823bd8SMatthew G Knepley PetscFunctionBegin; 419731823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 419831823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 419931823bd8SMatthew G Knepley if (!snes->pc) { 420031823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr); 42014a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr); 420231823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 420331823bd8SMatthew G Knepley } 420431823bd8SMatthew G Knepley *pc = snes->pc; 420531823bd8SMatthew G Knepley PetscFunctionReturn(0); 420631823bd8SMatthew G Knepley } 420731823bd8SMatthew G Knepley 42089e764e56SPeter Brune #undef __FUNCT__ 4209f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch" 42109e764e56SPeter Brune /*@ 4211f1c6b773SPeter Brune SNESSetSNESLineSearch - Sets the linesearch. 42129e764e56SPeter Brune 42139e764e56SPeter Brune Collective on SNES 42149e764e56SPeter Brune 42159e764e56SPeter Brune Input Parameters: 42169e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 42179e764e56SPeter Brune - linesearch - the linesearch object 42189e764e56SPeter Brune 42199e764e56SPeter Brune Notes: 4220f1c6b773SPeter Brune Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example, 42219e764e56SPeter Brune to configure it using the API). 42229e764e56SPeter Brune 42239e764e56SPeter Brune Level: developer 42249e764e56SPeter Brune 42259e764e56SPeter Brune .keywords: SNES, set, linesearch 4226f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch() 42279e764e56SPeter Brune @*/ 4228f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch) 42299e764e56SPeter Brune { 42309e764e56SPeter Brune PetscErrorCode ierr; 42319e764e56SPeter Brune 42329e764e56SPeter Brune PetscFunctionBegin; 42339e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4234f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 42359e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 42369e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 4237f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 42389e764e56SPeter Brune snes->linesearch = linesearch; 42399e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 42409e764e56SPeter Brune PetscFunctionReturn(0); 42419e764e56SPeter Brune } 42429e764e56SPeter Brune 42439e764e56SPeter Brune #undef __FUNCT__ 4244f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch" 4245ea5d4fccSPeter Brune /*@C 4246f1c6b773SPeter Brune SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch(). 42479e764e56SPeter Brune 42489e764e56SPeter Brune Not Collective 42499e764e56SPeter Brune 42509e764e56SPeter Brune Input Parameter: 42519e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 42529e764e56SPeter Brune 42539e764e56SPeter Brune Output Parameter: 42549e764e56SPeter Brune . linesearch - linesearch context 42559e764e56SPeter Brune 42569e764e56SPeter Brune Level: developer 42579e764e56SPeter Brune 42589e764e56SPeter Brune .keywords: SNES, get, linesearch 4259f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch() 42609e764e56SPeter Brune @*/ 4261f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch) 42629e764e56SPeter Brune { 42639e764e56SPeter Brune PetscErrorCode ierr; 42649e764e56SPeter Brune const char *optionsprefix; 42659e764e56SPeter Brune 42669e764e56SPeter Brune PetscFunctionBegin; 42679e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 42689e764e56SPeter Brune PetscValidPointer(linesearch, 2); 42699e764e56SPeter Brune if (!snes->linesearch) { 42709e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 4271f1c6b773SPeter Brune ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr); 4272f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 42739e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 42749e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 42759e764e56SPeter Brune } 42769e764e56SPeter Brune *linesearch = snes->linesearch; 42779e764e56SPeter Brune PetscFunctionReturn(0); 42789e764e56SPeter Brune } 42799e764e56SPeter Brune 428069b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4281c6db04a5SJed Brown #include <mex.h> 428269b4f73cSBarry Smith 42838f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 42848f6e6473SBarry Smith 42850807856dSBarry Smith #undef __FUNCT__ 42860807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 42870807856dSBarry Smith /* 42880807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 42890807856dSBarry Smith SNESSetFunctionMatlab(). 42900807856dSBarry Smith 42910807856dSBarry Smith Collective on SNES 42920807856dSBarry Smith 42930807856dSBarry Smith Input Parameters: 42940807856dSBarry Smith + snes - the SNES context 42950807856dSBarry Smith - x - input vector 42960807856dSBarry Smith 42970807856dSBarry Smith Output Parameter: 42980807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 42990807856dSBarry Smith 43000807856dSBarry Smith Notes: 43010807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 43020807856dSBarry Smith implementations, so most users would not generally call this routine 43030807856dSBarry Smith themselves. 43040807856dSBarry Smith 43050807856dSBarry Smith Level: developer 43060807856dSBarry Smith 43070807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 43080807856dSBarry Smith 43090807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 431061b2408cSBarry Smith */ 43117087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 43120807856dSBarry Smith { 4313e650e774SBarry Smith PetscErrorCode ierr; 43148f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 43158f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 43168f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 431791621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 4318e650e774SBarry Smith 43190807856dSBarry Smith PetscFunctionBegin; 43200807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 43210807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 43220807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 43230807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 43240807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 43250807856dSBarry Smith 43260807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 4327e650e774SBarry Smith 432891621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4329e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4330e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 433191621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 433291621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 433391621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 43348f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 43358f6e6473SBarry Smith prhs[4] = sctx->ctx; 4336b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 4337e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4338e650e774SBarry Smith mxDestroyArray(prhs[0]); 4339e650e774SBarry Smith mxDestroyArray(prhs[1]); 4340e650e774SBarry Smith mxDestroyArray(prhs[2]); 43418f6e6473SBarry Smith mxDestroyArray(prhs[3]); 4342e650e774SBarry Smith mxDestroyArray(plhs[0]); 43430807856dSBarry Smith PetscFunctionReturn(0); 43440807856dSBarry Smith } 43450807856dSBarry Smith 43460807856dSBarry Smith 43470807856dSBarry Smith #undef __FUNCT__ 43480807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 434961b2408cSBarry Smith /* 43500807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 43510807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4352e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 43530807856dSBarry Smith 43540807856dSBarry Smith Logically Collective on SNES 43550807856dSBarry Smith 43560807856dSBarry Smith Input Parameters: 43570807856dSBarry Smith + snes - the SNES context 43580807856dSBarry Smith . r - vector to store function value 43590807856dSBarry Smith - func - function evaluation routine 43600807856dSBarry Smith 43610807856dSBarry Smith Calling sequence of func: 436261b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 43630807856dSBarry Smith 43640807856dSBarry Smith 43650807856dSBarry Smith Notes: 43660807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 43670807856dSBarry Smith $ f'(x) x = -f(x), 43680807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 43690807856dSBarry Smith 43700807856dSBarry Smith Level: beginner 43710807856dSBarry Smith 43720807856dSBarry Smith .keywords: SNES, nonlinear, set, function 43730807856dSBarry Smith 43740807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 437561b2408cSBarry Smith */ 43767087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 43770807856dSBarry Smith { 43780807856dSBarry Smith PetscErrorCode ierr; 43798f6e6473SBarry Smith SNESMatlabContext *sctx; 43800807856dSBarry Smith 43810807856dSBarry Smith PetscFunctionBegin; 43828f6e6473SBarry Smith /* currently sctx is memory bleed */ 43838f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 43848f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 43858f6e6473SBarry Smith /* 43868f6e6473SBarry Smith This should work, but it doesn't 43878f6e6473SBarry Smith sctx->ctx = ctx; 43888f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 43898f6e6473SBarry Smith */ 43908f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 43918f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 43920807856dSBarry Smith PetscFunctionReturn(0); 43930807856dSBarry Smith } 439469b4f73cSBarry Smith 439561b2408cSBarry Smith #undef __FUNCT__ 439661b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 439761b2408cSBarry Smith /* 439861b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 439961b2408cSBarry Smith SNESSetJacobianMatlab(). 440061b2408cSBarry Smith 440161b2408cSBarry Smith Collective on SNES 440261b2408cSBarry Smith 440361b2408cSBarry Smith Input Parameters: 440461b2408cSBarry Smith + snes - the SNES context 440561b2408cSBarry Smith . x - input vector 440661b2408cSBarry Smith . A, B - the matrices 440761b2408cSBarry Smith - ctx - user context 440861b2408cSBarry Smith 440961b2408cSBarry Smith Output Parameter: 441061b2408cSBarry Smith . flag - structure of the matrix 441161b2408cSBarry Smith 441261b2408cSBarry Smith Level: developer 441361b2408cSBarry Smith 441461b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 441561b2408cSBarry Smith 441661b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 441761b2408cSBarry Smith @*/ 44187087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 441961b2408cSBarry Smith { 442061b2408cSBarry Smith PetscErrorCode ierr; 442161b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 442261b2408cSBarry Smith int nlhs = 2,nrhs = 6; 442361b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 442461b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 442561b2408cSBarry Smith 442661b2408cSBarry Smith PetscFunctionBegin; 442761b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 442861b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 442961b2408cSBarry Smith 443061b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 443161b2408cSBarry Smith 443261b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 443361b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 443461b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 443561b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 443661b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 443761b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 443861b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 443961b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 444061b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 444161b2408cSBarry Smith prhs[5] = sctx->ctx; 4442b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 444361b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 444461b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 444561b2408cSBarry Smith mxDestroyArray(prhs[0]); 444661b2408cSBarry Smith mxDestroyArray(prhs[1]); 444761b2408cSBarry Smith mxDestroyArray(prhs[2]); 444861b2408cSBarry Smith mxDestroyArray(prhs[3]); 444961b2408cSBarry Smith mxDestroyArray(prhs[4]); 445061b2408cSBarry Smith mxDestroyArray(plhs[0]); 445161b2408cSBarry Smith mxDestroyArray(plhs[1]); 445261b2408cSBarry Smith PetscFunctionReturn(0); 445361b2408cSBarry Smith } 445461b2408cSBarry Smith 445561b2408cSBarry Smith 445661b2408cSBarry Smith #undef __FUNCT__ 445761b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 445861b2408cSBarry Smith /* 445961b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 446061b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4461e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 446261b2408cSBarry Smith 446361b2408cSBarry Smith Logically Collective on SNES 446461b2408cSBarry Smith 446561b2408cSBarry Smith Input Parameters: 446661b2408cSBarry Smith + snes - the SNES context 446761b2408cSBarry Smith . A,B - Jacobian matrices 446861b2408cSBarry Smith . func - function evaluation routine 446961b2408cSBarry Smith - ctx - user context 447061b2408cSBarry Smith 447161b2408cSBarry Smith Calling sequence of func: 447261b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 447361b2408cSBarry Smith 447461b2408cSBarry Smith 447561b2408cSBarry Smith Level: developer 447661b2408cSBarry Smith 447761b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 447861b2408cSBarry Smith 447961b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 448061b2408cSBarry Smith */ 44817087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 448261b2408cSBarry Smith { 448361b2408cSBarry Smith PetscErrorCode ierr; 448461b2408cSBarry Smith SNESMatlabContext *sctx; 448561b2408cSBarry Smith 448661b2408cSBarry Smith PetscFunctionBegin; 448761b2408cSBarry Smith /* currently sctx is memory bleed */ 448861b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 448961b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 449061b2408cSBarry Smith /* 449161b2408cSBarry Smith This should work, but it doesn't 449261b2408cSBarry Smith sctx->ctx = ctx; 449361b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 449461b2408cSBarry Smith */ 449561b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 449661b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 449761b2408cSBarry Smith PetscFunctionReturn(0); 449861b2408cSBarry Smith } 449969b4f73cSBarry Smith 4500f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4501f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4502f9eb7ae2SShri Abhyankar /* 4503f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4504f9eb7ae2SShri Abhyankar 4505f9eb7ae2SShri Abhyankar Collective on SNES 4506f9eb7ae2SShri Abhyankar 4507f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4508f9eb7ae2SShri Abhyankar @*/ 45097087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4510f9eb7ae2SShri Abhyankar { 4511f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 451248f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4513f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4514f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4515f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4516f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4517f9eb7ae2SShri Abhyankar 4518f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4519f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4520f9eb7ae2SShri Abhyankar 4521f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4522f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4523f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4524f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4525f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4526f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4527f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4528f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4529f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4530f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4531f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4532f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4533f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4534f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4535f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4536f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4537f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4538f9eb7ae2SShri Abhyankar } 4539f9eb7ae2SShri Abhyankar 4540f9eb7ae2SShri Abhyankar 4541f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4542f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4543f9eb7ae2SShri Abhyankar /* 4544e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4545f9eb7ae2SShri Abhyankar 4546f9eb7ae2SShri Abhyankar Level: developer 4547f9eb7ae2SShri Abhyankar 4548f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4549f9eb7ae2SShri Abhyankar 4550f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4551f9eb7ae2SShri Abhyankar */ 45527087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4553f9eb7ae2SShri Abhyankar { 4554f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4555f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4556f9eb7ae2SShri Abhyankar 4557f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4558f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4559f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4560f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4561f9eb7ae2SShri Abhyankar /* 4562f9eb7ae2SShri Abhyankar This should work, but it doesn't 4563f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4564f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4565f9eb7ae2SShri Abhyankar */ 4566f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4567f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4568f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4569f9eb7ae2SShri Abhyankar } 4570f9eb7ae2SShri Abhyankar 457169b4f73cSBarry Smith #endif 4572