19b94acceSBarry Smith 2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h> /*I "petscsnes.h" I*/ 36cab3a1bSJed Brown #include <petscdmshell.h> /*I "petscdmshell.h" I*/ 49b94acceSBarry Smith 5ace3abfcSBarry Smith PetscBool SNESRegisterAllCalled = PETSC_FALSE; 68ba1e511SMatthew Knepley PetscFList SNESList = PETSC_NULL; 78ba1e511SMatthew Knepley 88ba1e511SMatthew Knepley /* Logging support */ 97087cfbeSBarry Smith PetscClassId SNES_CLASSID; 10f1c6b773SPeter Brune PetscLogEvent SNES_Solve, SNES_FunctionEval, SNES_JacobianEval, SNES_GSEval; 11a09944afSBarry Smith 12a09944afSBarry Smith #undef __FUNCT__ 13cab2e9ccSBarry Smith #define __FUNCT__ "SNESDMComputeJacobian" 14cab2e9ccSBarry Smith /* 15cab2e9ccSBarry Smith Translates from a SNES call to a DM call in computing a Jacobian 16caa4e7f2SJed Brown 17caa4e7f2SJed Brown This is a legacy calling sequence, should transition to dispatching through the SNESDM. 18cab2e9ccSBarry Smith */ 19cab2e9ccSBarry Smith PetscErrorCode SNESDMComputeJacobian(SNES snes,Vec X,Mat *J,Mat *B,MatStructure *flag,void *ptr) 20cab2e9ccSBarry Smith { 21cab2e9ccSBarry Smith PetscErrorCode ierr; 22cab2e9ccSBarry Smith DM dm; 23cab2e9ccSBarry Smith 24cab2e9ccSBarry Smith PetscFunctionBegin; 25cab2e9ccSBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 26cab2e9ccSBarry Smith ierr = DMComputeJacobian(dm,X,*J,*B,flag);CHKERRQ(ierr); 27cab2e9ccSBarry Smith PetscFunctionReturn(0); 28cab2e9ccSBarry Smith } 29cab2e9ccSBarry Smith 30cab2e9ccSBarry Smith #undef __FUNCT__ 31e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged" 32e113a28aSBarry Smith /*@ 33e113a28aSBarry Smith SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged. 34e113a28aSBarry Smith 353f9fe445SBarry Smith Logically Collective on SNES 36e113a28aSBarry Smith 37e113a28aSBarry Smith Input Parameters: 38e113a28aSBarry Smith + snes - iterative context obtained from SNESCreate() 39e113a28aSBarry Smith - flg - PETSC_TRUE indicates you want the error generated 40e113a28aSBarry Smith 41e113a28aSBarry Smith Options database keys: 42e113a28aSBarry Smith . -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false) 43e113a28aSBarry Smith 44e113a28aSBarry Smith Level: intermediate 45e113a28aSBarry Smith 46e113a28aSBarry Smith Notes: 47e113a28aSBarry Smith Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve() 48e113a28aSBarry Smith to determine if it has converged. 49e113a28aSBarry Smith 50e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 51e113a28aSBarry Smith 52e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 53e113a28aSBarry Smith @*/ 547087cfbeSBarry Smith PetscErrorCode SNESSetErrorIfNotConverged(SNES snes,PetscBool flg) 55e113a28aSBarry Smith { 56e113a28aSBarry Smith PetscFunctionBegin; 57e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 58acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flg,2); 59e113a28aSBarry Smith snes->errorifnotconverged = flg; 60dd568438SSatish Balay 61e113a28aSBarry Smith PetscFunctionReturn(0); 62e113a28aSBarry Smith } 63e113a28aSBarry Smith 64e113a28aSBarry Smith #undef __FUNCT__ 65e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged" 66e113a28aSBarry Smith /*@ 67e113a28aSBarry Smith SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge? 68e113a28aSBarry Smith 69e113a28aSBarry Smith Not Collective 70e113a28aSBarry Smith 71e113a28aSBarry Smith Input Parameter: 72e113a28aSBarry Smith . snes - iterative context obtained from SNESCreate() 73e113a28aSBarry Smith 74e113a28aSBarry Smith Output Parameter: 75e113a28aSBarry Smith . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE 76e113a28aSBarry Smith 77e113a28aSBarry Smith Level: intermediate 78e113a28aSBarry Smith 79e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 80e113a28aSBarry Smith 81e113a28aSBarry Smith .seealso: SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 82e113a28aSBarry Smith @*/ 837087cfbeSBarry Smith PetscErrorCode SNESGetErrorIfNotConverged(SNES snes,PetscBool *flag) 84e113a28aSBarry Smith { 85e113a28aSBarry Smith PetscFunctionBegin; 86e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 87e113a28aSBarry Smith PetscValidPointer(flag,2); 88e113a28aSBarry Smith *flag = snes->errorifnotconverged; 89e113a28aSBarry Smith PetscFunctionReturn(0); 90e113a28aSBarry Smith } 91e113a28aSBarry Smith 92e113a28aSBarry Smith #undef __FUNCT__ 934936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError" 94e725d27bSBarry Smith /*@ 954936397dSBarry Smith SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not 964936397dSBarry Smith in the functions domain. For example, negative pressure. 974936397dSBarry Smith 983f9fe445SBarry Smith Logically Collective on SNES 994936397dSBarry Smith 1004936397dSBarry Smith Input Parameters: 1016a388c36SPeter Brune . snes - the SNES context 1024936397dSBarry Smith 10328529972SSatish Balay Level: advanced 1044936397dSBarry Smith 1054936397dSBarry Smith .keywords: SNES, view 1064936397dSBarry Smith 1074936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction() 1084936397dSBarry Smith @*/ 1097087cfbeSBarry Smith PetscErrorCode SNESSetFunctionDomainError(SNES snes) 1104936397dSBarry Smith { 1114936397dSBarry Smith PetscFunctionBegin; 1120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1134936397dSBarry Smith snes->domainerror = PETSC_TRUE; 1144936397dSBarry Smith PetscFunctionReturn(0); 1154936397dSBarry Smith } 1164936397dSBarry Smith 1176a388c36SPeter Brune 1186a388c36SPeter Brune #undef __FUNCT__ 1196a388c36SPeter Brune #define __FUNCT__ "SNESGetFunctionDomainError" 1206a388c36SPeter Brune /*@ 121c77b2880SPeter Brune SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction; 1226a388c36SPeter Brune 1236a388c36SPeter Brune Logically Collective on SNES 1246a388c36SPeter Brune 1256a388c36SPeter Brune Input Parameters: 1266a388c36SPeter Brune . snes - the SNES context 1276a388c36SPeter Brune 1286a388c36SPeter Brune Output Parameters: 1296a388c36SPeter Brune . domainerror Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise. 1306a388c36SPeter Brune 1316a388c36SPeter Brune Level: advanced 1326a388c36SPeter Brune 1336a388c36SPeter Brune .keywords: SNES, view 1346a388c36SPeter Brune 1356a388c36SPeter Brune .seealso: SNESSetFunctionDomainError, SNESComputeFunction() 1366a388c36SPeter Brune @*/ 1376a388c36SPeter Brune PetscErrorCode SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror) 1386a388c36SPeter Brune { 1396a388c36SPeter Brune PetscFunctionBegin; 1406a388c36SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1416a388c36SPeter Brune PetscValidPointer(domainerror, 2); 1426a388c36SPeter Brune *domainerror = snes->domainerror; 1436a388c36SPeter Brune PetscFunctionReturn(0); 1446a388c36SPeter Brune } 1456a388c36SPeter Brune 1466a388c36SPeter Brune 1474936397dSBarry Smith #undef __FUNCT__ 1484a2ae208SSatish Balay #define __FUNCT__ "SNESView" 1497e2c5f70SBarry Smith /*@C 1509b94acceSBarry Smith SNESView - Prints the SNES data structure. 1519b94acceSBarry Smith 1524c49b128SBarry Smith Collective on SNES 153fee21e36SBarry Smith 154c7afd0dbSLois Curfman McInnes Input Parameters: 155c7afd0dbSLois Curfman McInnes + SNES - the SNES context 156c7afd0dbSLois Curfman McInnes - viewer - visualization context 157c7afd0dbSLois Curfman McInnes 1589b94acceSBarry Smith Options Database Key: 159c8a8ba5cSLois Curfman McInnes . -snes_view - Calls SNESView() at end of SNESSolve() 1609b94acceSBarry Smith 1619b94acceSBarry Smith Notes: 1629b94acceSBarry Smith The available visualization contexts include 163b0a32e0cSBarry Smith + PETSC_VIEWER_STDOUT_SELF - standard output (default) 164b0a32e0cSBarry Smith - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 165c8a8ba5cSLois Curfman McInnes output where only the first processor opens 166c8a8ba5cSLois Curfman McInnes the file. All other processors send their 167c8a8ba5cSLois Curfman McInnes data to the first processor to print. 1689b94acceSBarry Smith 1693e081fefSLois Curfman McInnes The user can open an alternative visualization context with 170b0a32e0cSBarry Smith PetscViewerASCIIOpen() - output to a specified file. 1719b94acceSBarry Smith 17236851e7fSLois Curfman McInnes Level: beginner 17336851e7fSLois Curfman McInnes 1749b94acceSBarry Smith .keywords: SNES, view 1759b94acceSBarry Smith 176b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen() 1779b94acceSBarry Smith @*/ 1787087cfbeSBarry Smith PetscErrorCode SNESView(SNES snes,PetscViewer viewer) 1799b94acceSBarry Smith { 180fa9f3622SBarry Smith SNESKSPEW *kctx; 181dfbe8321SBarry Smith PetscErrorCode ierr; 18294b7f48cSBarry Smith KSP ksp; 1837f1410a3SPeter Brune SNESLineSearch linesearch; 184ace3abfcSBarry Smith PetscBool iascii,isstring; 1859b94acceSBarry Smith 1863a40ed3dSBarry Smith PetscFunctionBegin; 1870700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1883050cee2SBarry Smith if (!viewer) { 1897adad957SLisandro Dalcin ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 1903050cee2SBarry Smith } 1910700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 192c9780b6fSBarry Smith PetscCheckSameComm(snes,1,viewer,2); 19374679c65SBarry Smith 1942692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1952692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 19632077d6dSBarry Smith if (iascii) { 197317d6ea6SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr); 198e7788613SBarry Smith if (snes->ops->view) { 199b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 200e7788613SBarry Smith ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 201b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2020ef38995SBarry Smith } 20377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr); 204a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%G, absolute=%G, solution=%G\n", 205c60f73f4SPeter Brune snes->rtol,snes->abstol,snes->stol);CHKERRQ(ierr); 20677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr); 20777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr); 2089b94acceSBarry Smith if (snes->ksp_ewconv) { 209fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 2109b94acceSBarry Smith if (kctx) { 21177431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr); 212a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr); 213a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr); 2149b94acceSBarry Smith } 2159b94acceSBarry Smith } 216eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 217eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n");CHKERRQ(ierr); 218eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 219eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr); 220eb1f6c34SBarry Smith } 221eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 222eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n");CHKERRQ(ierr); 223eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 22442f4f86dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr); 225eb1f6c34SBarry Smith } 2260f5bd95cSBarry Smith } else if (isstring) { 227317d6ea6SBarry Smith const char *type; 228454a90a3SBarry Smith ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 229b0a32e0cSBarry Smith ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr); 23019bcc07fSBarry Smith } 23142f4f86dSBarry Smith if (snes->pc && snes->usespc) { 2324a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2334a0c5b0cSMatthew G Knepley ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr); 2344a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2354a0c5b0cSMatthew G Knepley } 2362c155ee1SBarry Smith if (snes->usesksp) { 2372c155ee1SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 238b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 23994b7f48cSBarry Smith ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 240b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2412c155ee1SBarry Smith } 2427f1410a3SPeter Brune if (snes->linesearch) { 2437f1410a3SPeter Brune ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2447f1410a3SPeter Brune ierr = SNESGetSNESLineSearch(snes, &linesearch);CHKERRQ(ierr); 2457f1410a3SPeter Brune ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr); 2467f1410a3SPeter Brune ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2477f1410a3SPeter Brune } 2483a40ed3dSBarry Smith PetscFunctionReturn(0); 2499b94acceSBarry Smith } 2509b94acceSBarry Smith 25176b2cf59SMatthew Knepley /* 25276b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 25376b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 25476b2cf59SMatthew Knepley */ 25576b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 256a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 2576849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 25876b2cf59SMatthew Knepley 259e74ef692SMatthew Knepley #undef __FUNCT__ 260e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker" 261ac226902SBarry Smith /*@C 26276b2cf59SMatthew Knepley SNESAddOptionsChecker - Adds an additional function to check for SNES options. 26376b2cf59SMatthew Knepley 26476b2cf59SMatthew Knepley Not Collective 26576b2cf59SMatthew Knepley 26676b2cf59SMatthew Knepley Input Parameter: 26776b2cf59SMatthew Knepley . snescheck - function that checks for options 26876b2cf59SMatthew Knepley 26976b2cf59SMatthew Knepley Level: developer 27076b2cf59SMatthew Knepley 27176b2cf59SMatthew Knepley .seealso: SNESSetFromOptions() 27276b2cf59SMatthew Knepley @*/ 2737087cfbeSBarry Smith PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 27476b2cf59SMatthew Knepley { 27576b2cf59SMatthew Knepley PetscFunctionBegin; 27676b2cf59SMatthew Knepley if (numberofsetfromoptions >= MAXSETFROMOPTIONS) { 277e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 27876b2cf59SMatthew Knepley } 27976b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 28076b2cf59SMatthew Knepley PetscFunctionReturn(0); 28176b2cf59SMatthew Knepley } 28276b2cf59SMatthew Knepley 2837087cfbeSBarry Smith extern PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 284aa3661deSLisandro Dalcin 285aa3661deSLisandro Dalcin #undef __FUNCT__ 286aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private" 287ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 288aa3661deSLisandro Dalcin { 289aa3661deSLisandro Dalcin Mat J; 290aa3661deSLisandro Dalcin KSP ksp; 291aa3661deSLisandro Dalcin PC pc; 292ace3abfcSBarry Smith PetscBool match; 293aa3661deSLisandro Dalcin PetscErrorCode ierr; 294aa3661deSLisandro Dalcin 295aa3661deSLisandro Dalcin PetscFunctionBegin; 2960700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 297aa3661deSLisandro Dalcin 29898613b67SLisandro Dalcin if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 29998613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 30098613b67SLisandro Dalcin ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr); 30198613b67SLisandro Dalcin } 30298613b67SLisandro Dalcin 303aa3661deSLisandro Dalcin if (version == 1) { 304aa3661deSLisandro Dalcin ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 30598613b67SLisandro Dalcin ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 3069c6ac3b3SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 307aa3661deSLisandro Dalcin } else if (version == 2) { 308e32f2f54SBarry Smith if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 30982a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 310aa3661deSLisandro Dalcin ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr); 311aa3661deSLisandro Dalcin #else 312e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)"); 313aa3661deSLisandro Dalcin #endif 314a8248277SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2"); 315aa3661deSLisandro Dalcin 316aa3661deSLisandro Dalcin ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr); 317d3462f78SMatthew Knepley if (hasOperator) { 318aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 319aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 320aa3661deSLisandro Dalcin ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 321aa3661deSLisandro Dalcin } else { 322aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 323aa3661deSLisandro Dalcin provided preconditioner matrix with the default matrix free version. */ 3246cab3a1bSJed Brown void *functx; 3256cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 3266cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr); 327aa3661deSLisandro Dalcin /* Force no preconditioner */ 328aa3661deSLisandro Dalcin ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 329aa3661deSLisandro Dalcin ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 330aa3661deSLisandro Dalcin ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr); 331aa3661deSLisandro Dalcin if (!match) { 332aa3661deSLisandro Dalcin ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 333aa3661deSLisandro Dalcin ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 334aa3661deSLisandro Dalcin } 335aa3661deSLisandro Dalcin } 3366bf464f9SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 337aa3661deSLisandro Dalcin PetscFunctionReturn(0); 338aa3661deSLisandro Dalcin } 339aa3661deSLisandro Dalcin 3404a2ae208SSatish Balay #undef __FUNCT__ 341dfe15315SJed Brown #define __FUNCT__ "DMRestrictHook_SNESVecSol" 342dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx) 343dfe15315SJed Brown { 344dfe15315SJed Brown SNES snes = (SNES)ctx; 345dfe15315SJed Brown PetscErrorCode ierr; 346dfe15315SJed Brown Vec Xfine,Xfine_named = PETSC_NULL,Xcoarse; 347dfe15315SJed Brown 348dfe15315SJed Brown PetscFunctionBegin; 349dfe15315SJed Brown if (dmfine == snes->dm) Xfine = snes->vec_sol; 350dfe15315SJed Brown else { 351dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr); 352dfe15315SJed Brown Xfine = Xfine_named; 353dfe15315SJed Brown } 354dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 355dfe15315SJed Brown ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr); 356dfe15315SJed Brown ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr); 357dfe15315SJed Brown ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 358dfe15315SJed Brown if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);} 359dfe15315SJed Brown PetscFunctionReturn(0); 360dfe15315SJed Brown } 361dfe15315SJed Brown 362dfe15315SJed Brown #undef __FUNCT__ 363caa4e7f2SJed Brown #define __FUNCT__ "KSPComputeOperators_SNES" 364caa4e7f2SJed Brown static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,MatStructure *mstruct,void *ctx) 365caa4e7f2SJed Brown { 366caa4e7f2SJed Brown SNES snes = (SNES)ctx; 367caa4e7f2SJed Brown PetscErrorCode ierr; 368caa4e7f2SJed Brown Mat Asave = A,Bsave = B; 369dfe15315SJed Brown Vec X,Xnamed = PETSC_NULL; 370dfe15315SJed Brown DM dmsave; 371caa4e7f2SJed Brown 372caa4e7f2SJed Brown PetscFunctionBegin; 373dfe15315SJed Brown dmsave = snes->dm; 374dfe15315SJed Brown ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr); 375dfe15315SJed Brown if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */ 376dfe15315SJed Brown else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ 377dfe15315SJed Brown ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 378dfe15315SJed Brown X = Xnamed; 379dfe15315SJed Brown } 380dfe15315SJed Brown ierr = SNESComputeJacobian(snes,X,&A,&B,mstruct);CHKERRQ(ierr); 381caa4e7f2SJed Brown if (A != Asave || B != Bsave) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"No support for changing matrices at this time"); 382dfe15315SJed Brown if (Xnamed) { 383dfe15315SJed Brown ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 384dfe15315SJed Brown } 385dfe15315SJed Brown snes->dm = dmsave; 386caa4e7f2SJed Brown PetscFunctionReturn(0); 387caa4e7f2SJed Brown } 388caa4e7f2SJed Brown 389caa4e7f2SJed Brown #undef __FUNCT__ 3906cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices" 3916cab3a1bSJed Brown /*@ 3926cab3a1bSJed Brown SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX() 3936cab3a1bSJed Brown 3946cab3a1bSJed Brown Collective 3956cab3a1bSJed Brown 3966cab3a1bSJed Brown Input Arguments: 3976cab3a1bSJed Brown . snes - snes to configure 3986cab3a1bSJed Brown 3996cab3a1bSJed Brown Level: developer 4006cab3a1bSJed Brown 4016cab3a1bSJed Brown .seealso: SNESSetUp() 4026cab3a1bSJed Brown @*/ 4036cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes) 4046cab3a1bSJed Brown { 4056cab3a1bSJed Brown PetscErrorCode ierr; 4066cab3a1bSJed Brown DM dm; 4076cab3a1bSJed Brown SNESDM sdm; 4086cab3a1bSJed Brown 4096cab3a1bSJed Brown PetscFunctionBegin; 4106cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4116cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 412caa4e7f2SJed Brown if (!sdm->computejacobian) { 4136cab3a1bSJed Brown Mat J,B; 4146cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 4156cab3a1bSJed Brown if (snes->mf_operator) { 4166cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4176cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4186cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4196cab3a1bSJed Brown } else { 4206cab3a1bSJed Brown J = B; 4216cab3a1bSJed Brown ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr); 4226cab3a1bSJed Brown } 4236cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr); 4246cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 4256cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 4266cab3a1bSJed Brown } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) { 4276cab3a1bSJed Brown Mat J; 4286cab3a1bSJed Brown void *functx; 4296cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4306cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4316cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4326cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 4336cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr); 4346cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 435caa4e7f2SJed Brown } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 4366cab3a1bSJed Brown Mat J,B; 4376cab3a1bSJed Brown void *functx; 4386cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4396cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4406cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4416cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 4426cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 4436cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,functx);CHKERRQ(ierr); 4446cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 4456cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 446caa4e7f2SJed Brown } else if (!snes->jacobian_pre) { 4476cab3a1bSJed Brown Mat J,B; 4486cab3a1bSJed Brown J = snes->jacobian; 4496cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 4506cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 4516cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 4526cab3a1bSJed Brown } 453caa4e7f2SJed Brown { 454caa4e7f2SJed Brown PetscBool flg = PETSC_FALSE; 455caa4e7f2SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_kspcompute",&flg,PETSC_NULL);CHKERRQ(ierr); 456caa4e7f2SJed Brown if (flg) { /* Plan to transition to this model */ 457caa4e7f2SJed Brown KSP ksp; 458caa4e7f2SJed Brown ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 459caa4e7f2SJed Brown ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr); 460dfe15315SJed Brown ierr = DMCoarsenHookAdd(snes->dm,PETSC_NULL,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 461caa4e7f2SJed Brown } 462caa4e7f2SJed Brown } 4636cab3a1bSJed Brown PetscFunctionReturn(0); 4646cab3a1bSJed Brown } 4656cab3a1bSJed Brown 4666cab3a1bSJed Brown #undef __FUNCT__ 4674a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions" 4689b94acceSBarry Smith /*@ 46994b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 4709b94acceSBarry Smith 471c7afd0dbSLois Curfman McInnes Collective on SNES 472c7afd0dbSLois Curfman McInnes 4739b94acceSBarry Smith Input Parameter: 4749b94acceSBarry Smith . snes - the SNES context 4759b94acceSBarry Smith 47636851e7fSLois Curfman McInnes Options Database Keys: 477ea630c6eSPeter Brune + -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas 47882738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 47982738288SBarry Smith of the change in the solution between steps 48070441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 481b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 482b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 483b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 4844839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 485ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 486a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 487e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 488b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 4892492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 49082738288SBarry Smith solver; hence iterations will continue until max_it 4911fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 49282738288SBarry Smith of convergence test 493e8105e01SRichard Katz . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 494e8105e01SRichard Katz filename given prints to stdout 495a6570f20SBarry Smith . -snes_monitor_solution - plots solution at each iteration 496a6570f20SBarry Smith . -snes_monitor_residual - plots residual (not its norm) at each iteration 497a6570f20SBarry Smith . -snes_monitor_solution_update - plots update to solution at each iteration 498a6570f20SBarry Smith . -snes_monitor_draw - plots residual norm at each iteration 499e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 5005968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 501fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 50282738288SBarry Smith 50382738288SBarry Smith Options Database for Eisenstat-Walker method: 504fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 5054b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 50636851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 50736851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 50836851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 50936851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 51036851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 51136851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 51282738288SBarry Smith 51311ca99fdSLois Curfman McInnes Notes: 51411ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 5150598bfebSBarry Smith the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>. 51683e2fdc7SBarry Smith 51736851e7fSLois Curfman McInnes Level: beginner 51836851e7fSLois Curfman McInnes 5199b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 5209b94acceSBarry Smith 52169ed319cSSatish Balay .seealso: SNESSetOptionsPrefix() 5229b94acceSBarry Smith @*/ 5237087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 5249b94acceSBarry Smith { 525872b6db9SPeter Brune PetscBool flg,mf,mf_operator,pcset; 526efd51863SBarry Smith PetscInt i,indx,lag,mf_version,grids; 527aa3661deSLisandro Dalcin MatStructure matflag; 52885385478SLisandro Dalcin const char *deft = SNESLS; 52985385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 53085385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 531e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 53251e86f29SPeter Brune const char *optionsprefix; 533649052a6SBarry Smith PetscViewer monviewer; 53485385478SLisandro Dalcin PetscErrorCode ierr; 5359b94acceSBarry Smith 5363a40ed3dSBarry Smith PetscFunctionBegin; 5370700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 538ca161407SBarry Smith 539186905e3SBarry Smith if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 5403194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 5417adad957SLisandro Dalcin if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; } 542b0a32e0cSBarry Smith ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 543d64ed03dSBarry Smith if (flg) { 544186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 5457adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 546186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 547d64ed03dSBarry Smith } 54890d69ab7SBarry Smith /* not used here, but called so will go into help messaage */ 549909c8a9fSBarry Smith ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 55093c39befSBarry Smith 551c60f73f4SPeter Brune ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr); 55257034d6fSHong Zhang ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 553186905e3SBarry Smith 55457034d6fSHong Zhang ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 555b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 556b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 55750ffb88aSMatthew Knepley ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 558ddf469c8SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr); 559acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr); 56085385478SLisandro Dalcin 561a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 562a8054027SBarry Smith if (flg) { 563a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 564a8054027SBarry Smith } 565e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 566e35cf81dSBarry Smith if (flg) { 567e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 568e35cf81dSBarry Smith } 569efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 570efd51863SBarry Smith if (flg) { 571efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 572efd51863SBarry Smith } 573a8054027SBarry Smith 57485385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 57585385478SLisandro Dalcin if (flg) { 57685385478SLisandro Dalcin switch (indx) { 5777f7931b9SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 5787f7931b9SBarry Smith case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 57985385478SLisandro Dalcin } 58085385478SLisandro Dalcin } 58185385478SLisandro Dalcin 582acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr); 583186905e3SBarry Smith 58485385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 58585385478SLisandro Dalcin 586acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 587186905e3SBarry Smith 588fa9f3622SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 589fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 590fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 591fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 592fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 593fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 594fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 595186905e3SBarry Smith 59690d69ab7SBarry Smith flg = PETSC_FALSE; 597acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 598a6570f20SBarry Smith if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 599eabae89aSBarry Smith 600a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 601e8105e01SRichard Katz if (flg) { 602649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 603649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 604e8105e01SRichard Katz } 605eabae89aSBarry Smith 606b271bb04SBarry Smith ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 607b271bb04SBarry Smith if (flg) { 608b271bb04SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 609b271bb04SBarry Smith } 610b271bb04SBarry Smith 611a6570f20SBarry Smith ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 612eabae89aSBarry Smith if (flg) { 613649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 614f1bef1bcSMatthew Knepley ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 615e8105e01SRichard Katz } 616eabae89aSBarry Smith 617a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 618eabae89aSBarry Smith if (flg) { 619649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 620649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 621eabae89aSBarry Smith } 622eabae89aSBarry Smith 6235180491cSLisandro Dalcin ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 6245180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 6255180491cSLisandro Dalcin 62690d69ab7SBarry Smith flg = PETSC_FALSE; 627acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 628a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 62990d69ab7SBarry Smith flg = PETSC_FALSE; 630acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 631a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 63290d69ab7SBarry Smith flg = PETSC_FALSE; 633acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 634a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 63590d69ab7SBarry Smith flg = PETSC_FALSE; 636acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 637a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 63890d69ab7SBarry Smith flg = PETSC_FALSE; 639acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 640b271bb04SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 641e24b481bSBarry Smith 64290d69ab7SBarry Smith flg = PETSC_FALSE; 643acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 6444b27c08aSLois Curfman McInnes if (flg) { 6456cab3a1bSJed Brown void *functx; 6466cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 6476cab3a1bSJed Brown ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr); 648ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 6499b94acceSBarry Smith } 650639f9d9dSBarry Smith 651aa3661deSLisandro Dalcin mf = mf_operator = PETSC_FALSE; 652aa3661deSLisandro Dalcin flg = PETSC_FALSE; 653acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr); 654a8248277SBarry Smith if (flg && mf_operator) { 655a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 656a8248277SBarry Smith mf = PETSC_TRUE; 657a8248277SBarry Smith } 658aa3661deSLisandro Dalcin flg = PETSC_FALSE; 659acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr); 660aa3661deSLisandro Dalcin if (!flg && mf_operator) mf = PETSC_TRUE; 661aa3661deSLisandro Dalcin mf_version = 1; 662aa3661deSLisandro Dalcin ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr); 663aa3661deSLisandro Dalcin 664d28543b3SPeter Brune 66589b92e6fSPeter Brune /* GS Options */ 66689b92e6fSPeter Brune ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr); 66789b92e6fSPeter Brune 66876b2cf59SMatthew Knepley for(i = 0; i < numberofsetfromoptions; i++) { 66976b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 67076b2cf59SMatthew Knepley } 67176b2cf59SMatthew Knepley 672e7788613SBarry Smith if (snes->ops->setfromoptions) { 673e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 674639f9d9dSBarry Smith } 6755d973c19SBarry Smith 6765d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 6775d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 678b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 6794bbc92c1SBarry Smith 680aa3661deSLisandro Dalcin if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 6811cee3971SBarry Smith 6821cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 683aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 684aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 68585385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 68693993e2dSLois Curfman McInnes 6879e764e56SPeter Brune if (!snes->linesearch) { 688f1c6b773SPeter Brune ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 6899e764e56SPeter Brune } 690f1c6b773SPeter Brune ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr); 6919e764e56SPeter Brune 69251e86f29SPeter Brune /* if someone has set the SNES PC type, create it. */ 69351e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 69451e86f29SPeter Brune ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 69551e86f29SPeter Brune if (pcset && (!snes->pc)) { 69651e86f29SPeter Brune ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr); 69751e86f29SPeter Brune } 6984a0c5b0cSMatthew G Knepley if (snes->pc) { 699fde0ff24SPeter Brune ierr = SNESSetOptionsPrefix(snes->pc, optionsprefix);CHKERRQ(ierr); 700fde0ff24SPeter Brune ierr = SNESAppendOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr); 7014a0c5b0cSMatthew G Knepley ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 70288976e71SPeter Brune /* default to 1 iteration */ 70388976e71SPeter Brune ierr = SNESSetTolerances(snes->pc, snes->pc->abstol, snes->pc->rtol, snes->pc->stol, 1, snes->pc->max_funcs);CHKERRQ(ierr); 7044a0c5b0cSMatthew G Knepley ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 7054a0c5b0cSMatthew G Knepley } 7063a40ed3dSBarry Smith PetscFunctionReturn(0); 7079b94acceSBarry Smith } 7089b94acceSBarry Smith 709d25893d9SBarry Smith #undef __FUNCT__ 710d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 711d25893d9SBarry Smith /*@ 712d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 713d25893d9SBarry Smith the nonlinear solvers. 714d25893d9SBarry Smith 715d25893d9SBarry Smith Logically Collective on SNES 716d25893d9SBarry Smith 717d25893d9SBarry Smith Input Parameters: 718d25893d9SBarry Smith + snes - the SNES context 719d25893d9SBarry Smith . compute - function to compute the context 720d25893d9SBarry Smith - destroy - function to destroy the context 721d25893d9SBarry Smith 722d25893d9SBarry Smith Level: intermediate 723d25893d9SBarry Smith 724d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 725d25893d9SBarry Smith 726d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 727d25893d9SBarry Smith @*/ 728d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 729d25893d9SBarry Smith { 730d25893d9SBarry Smith PetscFunctionBegin; 731d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 732d25893d9SBarry Smith snes->ops->usercompute = compute; 733d25893d9SBarry Smith snes->ops->userdestroy = destroy; 734d25893d9SBarry Smith PetscFunctionReturn(0); 735d25893d9SBarry Smith } 736a847f771SSatish Balay 7374a2ae208SSatish Balay #undef __FUNCT__ 7384a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 739b07ff414SBarry Smith /*@ 7409b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 7419b94acceSBarry Smith the nonlinear solvers. 7429b94acceSBarry Smith 7433f9fe445SBarry Smith Logically Collective on SNES 744fee21e36SBarry Smith 745c7afd0dbSLois Curfman McInnes Input Parameters: 746c7afd0dbSLois Curfman McInnes + snes - the SNES context 747c7afd0dbSLois Curfman McInnes - usrP - optional user context 748c7afd0dbSLois Curfman McInnes 74936851e7fSLois Curfman McInnes Level: intermediate 75036851e7fSLois Curfman McInnes 7519b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 7529b94acceSBarry Smith 753d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext() 7549b94acceSBarry Smith @*/ 7557087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 7569b94acceSBarry Smith { 7571b2093e4SBarry Smith PetscErrorCode ierr; 758b07ff414SBarry Smith KSP ksp; 7591b2093e4SBarry Smith 7603a40ed3dSBarry Smith PetscFunctionBegin; 7610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 762b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 763b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 7649b94acceSBarry Smith snes->user = usrP; 7653a40ed3dSBarry Smith PetscFunctionReturn(0); 7669b94acceSBarry Smith } 76774679c65SBarry Smith 7684a2ae208SSatish Balay #undef __FUNCT__ 7694a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 770b07ff414SBarry Smith /*@ 7719b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 7729b94acceSBarry Smith nonlinear solvers. 7739b94acceSBarry Smith 774c7afd0dbSLois Curfman McInnes Not Collective 775c7afd0dbSLois Curfman McInnes 7769b94acceSBarry Smith Input Parameter: 7779b94acceSBarry Smith . snes - SNES context 7789b94acceSBarry Smith 7799b94acceSBarry Smith Output Parameter: 7809b94acceSBarry Smith . usrP - user context 7819b94acceSBarry Smith 78236851e7fSLois Curfman McInnes Level: intermediate 78336851e7fSLois Curfman McInnes 7849b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 7859b94acceSBarry Smith 7869b94acceSBarry Smith .seealso: SNESSetApplicationContext() 7879b94acceSBarry Smith @*/ 788e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 7899b94acceSBarry Smith { 7903a40ed3dSBarry Smith PetscFunctionBegin; 7910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 792e71120c6SJed Brown *(void**)usrP = snes->user; 7933a40ed3dSBarry Smith PetscFunctionReturn(0); 7949b94acceSBarry Smith } 79574679c65SBarry Smith 7964a2ae208SSatish Balay #undef __FUNCT__ 7974a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 7989b94acceSBarry Smith /*@ 799c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 800c8228a4eSBarry Smith at this time. 8019b94acceSBarry Smith 802c7afd0dbSLois Curfman McInnes Not Collective 803c7afd0dbSLois Curfman McInnes 8049b94acceSBarry Smith Input Parameter: 8059b94acceSBarry Smith . snes - SNES context 8069b94acceSBarry Smith 8079b94acceSBarry Smith Output Parameter: 8089b94acceSBarry Smith . iter - iteration number 8099b94acceSBarry Smith 810c8228a4eSBarry Smith Notes: 811c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 812c8228a4eSBarry Smith 813c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 81408405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 81508405cd6SLois Curfman McInnes .vb 81608405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 81708405cd6SLois Curfman McInnes if (!(it % 2)) { 81808405cd6SLois Curfman McInnes [compute Jacobian here] 81908405cd6SLois Curfman McInnes } 82008405cd6SLois Curfman McInnes .ve 821c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 82208405cd6SLois Curfman McInnes recomputed every second SNES iteration. 823c8228a4eSBarry Smith 82436851e7fSLois Curfman McInnes Level: intermediate 82536851e7fSLois Curfman McInnes 8262b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 8272b668275SBarry Smith 828b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 8299b94acceSBarry Smith @*/ 8307087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 8319b94acceSBarry Smith { 8323a40ed3dSBarry Smith PetscFunctionBegin; 8330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8344482741eSBarry Smith PetscValidIntPointer(iter,2); 8359b94acceSBarry Smith *iter = snes->iter; 8363a40ed3dSBarry Smith PetscFunctionReturn(0); 8379b94acceSBarry Smith } 83874679c65SBarry Smith 8394a2ae208SSatish Balay #undef __FUNCT__ 840360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber" 841360c497dSPeter Brune /*@ 842360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 843360c497dSPeter Brune 844360c497dSPeter Brune Not Collective 845360c497dSPeter Brune 846360c497dSPeter Brune Input Parameter: 847360c497dSPeter Brune . snes - SNES context 848360c497dSPeter Brune . iter - iteration number 849360c497dSPeter Brune 850360c497dSPeter Brune Level: developer 851360c497dSPeter Brune 852360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number, 853360c497dSPeter Brune 854360c497dSPeter Brune .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 855360c497dSPeter Brune @*/ 856360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 857360c497dSPeter Brune { 858360c497dSPeter Brune PetscErrorCode ierr; 859360c497dSPeter Brune 860360c497dSPeter Brune PetscFunctionBegin; 861360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 862360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 863360c497dSPeter Brune snes->iter = iter; 864360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 865360c497dSPeter Brune PetscFunctionReturn(0); 866360c497dSPeter Brune } 867360c497dSPeter Brune 868360c497dSPeter Brune #undef __FUNCT__ 8694a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 8709b94acceSBarry Smith /*@ 8719b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 8729b94acceSBarry Smith with SNESSSetFunction(). 8739b94acceSBarry Smith 874c7afd0dbSLois Curfman McInnes Collective on SNES 875c7afd0dbSLois Curfman McInnes 8769b94acceSBarry Smith Input Parameter: 8779b94acceSBarry Smith . snes - SNES context 8789b94acceSBarry Smith 8799b94acceSBarry Smith Output Parameter: 8809b94acceSBarry Smith . fnorm - 2-norm of function 8819b94acceSBarry Smith 88236851e7fSLois Curfman McInnes Level: intermediate 88336851e7fSLois Curfman McInnes 8849b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 885a86d99e1SLois Curfman McInnes 886b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 8879b94acceSBarry Smith @*/ 8887087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 8899b94acceSBarry Smith { 8903a40ed3dSBarry Smith PetscFunctionBegin; 8910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8924482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 8939b94acceSBarry Smith *fnorm = snes->norm; 8943a40ed3dSBarry Smith PetscFunctionReturn(0); 8959b94acceSBarry Smith } 89674679c65SBarry Smith 897360c497dSPeter Brune 898360c497dSPeter Brune #undef __FUNCT__ 899360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm" 900360c497dSPeter Brune /*@ 901360c497dSPeter Brune SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm(). 902360c497dSPeter Brune 903360c497dSPeter Brune Collective on SNES 904360c497dSPeter Brune 905360c497dSPeter Brune Input Parameter: 906360c497dSPeter Brune . snes - SNES context 907360c497dSPeter Brune . fnorm - 2-norm of function 908360c497dSPeter Brune 909360c497dSPeter Brune Level: developer 910360c497dSPeter Brune 911360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm 912360c497dSPeter Brune 913360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm(). 914360c497dSPeter Brune @*/ 915360c497dSPeter Brune PetscErrorCode SNESSetFunctionNorm(SNES snes,PetscReal fnorm) 916360c497dSPeter Brune { 917360c497dSPeter Brune 918360c497dSPeter Brune PetscErrorCode ierr; 919360c497dSPeter Brune 920360c497dSPeter Brune PetscFunctionBegin; 921360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 922360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 923360c497dSPeter Brune snes->norm = fnorm; 924360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 925360c497dSPeter Brune PetscFunctionReturn(0); 926360c497dSPeter Brune } 927360c497dSPeter Brune 9284a2ae208SSatish Balay #undef __FUNCT__ 929b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 9309b94acceSBarry Smith /*@ 931b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 9329b94acceSBarry Smith attempted by the nonlinear solver. 9339b94acceSBarry Smith 934c7afd0dbSLois Curfman McInnes Not Collective 935c7afd0dbSLois Curfman McInnes 9369b94acceSBarry Smith Input Parameter: 9379b94acceSBarry Smith . snes - SNES context 9389b94acceSBarry Smith 9399b94acceSBarry Smith Output Parameter: 9409b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 9419b94acceSBarry Smith 942c96a6f78SLois Curfman McInnes Notes: 943c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 944c96a6f78SLois Curfman McInnes 94536851e7fSLois Curfman McInnes Level: intermediate 94636851e7fSLois Curfman McInnes 9479b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 94858ebbce7SBarry Smith 949e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 95058ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 9519b94acceSBarry Smith @*/ 9527087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 9539b94acceSBarry Smith { 9543a40ed3dSBarry Smith PetscFunctionBegin; 9550700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9564482741eSBarry Smith PetscValidIntPointer(nfails,2); 95750ffb88aSMatthew Knepley *nfails = snes->numFailures; 95850ffb88aSMatthew Knepley PetscFunctionReturn(0); 95950ffb88aSMatthew Knepley } 96050ffb88aSMatthew Knepley 96150ffb88aSMatthew Knepley #undef __FUNCT__ 962b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 96350ffb88aSMatthew Knepley /*@ 964b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 96550ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 96650ffb88aSMatthew Knepley 96750ffb88aSMatthew Knepley Not Collective 96850ffb88aSMatthew Knepley 96950ffb88aSMatthew Knepley Input Parameters: 97050ffb88aSMatthew Knepley + snes - SNES context 97150ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 97250ffb88aSMatthew Knepley 97350ffb88aSMatthew Knepley Level: intermediate 97450ffb88aSMatthew Knepley 97550ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 97658ebbce7SBarry Smith 977e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 97858ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 97950ffb88aSMatthew Knepley @*/ 9807087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 98150ffb88aSMatthew Knepley { 98250ffb88aSMatthew Knepley PetscFunctionBegin; 9830700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 98450ffb88aSMatthew Knepley snes->maxFailures = maxFails; 98550ffb88aSMatthew Knepley PetscFunctionReturn(0); 98650ffb88aSMatthew Knepley } 98750ffb88aSMatthew Knepley 98850ffb88aSMatthew Knepley #undef __FUNCT__ 989b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 99050ffb88aSMatthew Knepley /*@ 991b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 99250ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 99350ffb88aSMatthew Knepley 99450ffb88aSMatthew Knepley Not Collective 99550ffb88aSMatthew Knepley 99650ffb88aSMatthew Knepley Input Parameter: 99750ffb88aSMatthew Knepley . snes - SNES context 99850ffb88aSMatthew Knepley 99950ffb88aSMatthew Knepley Output Parameter: 100050ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 100150ffb88aSMatthew Knepley 100250ffb88aSMatthew Knepley Level: intermediate 100350ffb88aSMatthew Knepley 100450ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 100558ebbce7SBarry Smith 1006e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 100758ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 100858ebbce7SBarry Smith 100950ffb88aSMatthew Knepley @*/ 10107087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 101150ffb88aSMatthew Knepley { 101250ffb88aSMatthew Knepley PetscFunctionBegin; 10130700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10144482741eSBarry Smith PetscValidIntPointer(maxFails,2); 101550ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 10163a40ed3dSBarry Smith PetscFunctionReturn(0); 10179b94acceSBarry Smith } 1018a847f771SSatish Balay 10194a2ae208SSatish Balay #undef __FUNCT__ 10202541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 10212541af92SBarry Smith /*@ 10222541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 10232541af92SBarry Smith done by SNES. 10242541af92SBarry Smith 10252541af92SBarry Smith Not Collective 10262541af92SBarry Smith 10272541af92SBarry Smith Input Parameter: 10282541af92SBarry Smith . snes - SNES context 10292541af92SBarry Smith 10302541af92SBarry Smith Output Parameter: 10312541af92SBarry Smith . nfuncs - number of evaluations 10322541af92SBarry Smith 10332541af92SBarry Smith Level: intermediate 10342541af92SBarry Smith 10352541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 103658ebbce7SBarry Smith 1037e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 10382541af92SBarry Smith @*/ 10397087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 10402541af92SBarry Smith { 10412541af92SBarry Smith PetscFunctionBegin; 10420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10432541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 10442541af92SBarry Smith *nfuncs = snes->nfuncs; 10452541af92SBarry Smith PetscFunctionReturn(0); 10462541af92SBarry Smith } 10472541af92SBarry Smith 10482541af92SBarry Smith #undef __FUNCT__ 10493d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 10503d4c4710SBarry Smith /*@ 10513d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 10523d4c4710SBarry Smith linear solvers. 10533d4c4710SBarry Smith 10543d4c4710SBarry Smith Not Collective 10553d4c4710SBarry Smith 10563d4c4710SBarry Smith Input Parameter: 10573d4c4710SBarry Smith . snes - SNES context 10583d4c4710SBarry Smith 10593d4c4710SBarry Smith Output Parameter: 10603d4c4710SBarry Smith . nfails - number of failed solves 10613d4c4710SBarry Smith 10623d4c4710SBarry Smith Notes: 10633d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 10643d4c4710SBarry Smith 10653d4c4710SBarry Smith Level: intermediate 10663d4c4710SBarry Smith 10673d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 106858ebbce7SBarry Smith 1069e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 10703d4c4710SBarry Smith @*/ 10717087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 10723d4c4710SBarry Smith { 10733d4c4710SBarry Smith PetscFunctionBegin; 10740700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10753d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 10763d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 10773d4c4710SBarry Smith PetscFunctionReturn(0); 10783d4c4710SBarry Smith } 10793d4c4710SBarry Smith 10803d4c4710SBarry Smith #undef __FUNCT__ 10813d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 10823d4c4710SBarry Smith /*@ 10833d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 10843d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 10853d4c4710SBarry Smith 10863f9fe445SBarry Smith Logically Collective on SNES 10873d4c4710SBarry Smith 10883d4c4710SBarry Smith Input Parameters: 10893d4c4710SBarry Smith + snes - SNES context 10903d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 10913d4c4710SBarry Smith 10923d4c4710SBarry Smith Level: intermediate 10933d4c4710SBarry Smith 1094a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 10953d4c4710SBarry Smith 10963d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 10973d4c4710SBarry Smith 109858ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 10993d4c4710SBarry Smith @*/ 11007087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 11013d4c4710SBarry Smith { 11023d4c4710SBarry Smith PetscFunctionBegin; 11030700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1104c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 11053d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 11063d4c4710SBarry Smith PetscFunctionReturn(0); 11073d4c4710SBarry Smith } 11083d4c4710SBarry Smith 11093d4c4710SBarry Smith #undef __FUNCT__ 11103d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 11113d4c4710SBarry Smith /*@ 11123d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 11133d4c4710SBarry Smith are allowed before SNES terminates 11143d4c4710SBarry Smith 11153d4c4710SBarry Smith Not Collective 11163d4c4710SBarry Smith 11173d4c4710SBarry Smith Input Parameter: 11183d4c4710SBarry Smith . snes - SNES context 11193d4c4710SBarry Smith 11203d4c4710SBarry Smith Output Parameter: 11213d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 11223d4c4710SBarry Smith 11233d4c4710SBarry Smith Level: intermediate 11243d4c4710SBarry Smith 11253d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 11263d4c4710SBarry Smith 11273d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 11283d4c4710SBarry Smith 1129e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 11303d4c4710SBarry Smith @*/ 11317087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 11323d4c4710SBarry Smith { 11333d4c4710SBarry Smith PetscFunctionBegin; 11340700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11353d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 11363d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 11373d4c4710SBarry Smith PetscFunctionReturn(0); 11383d4c4710SBarry Smith } 11393d4c4710SBarry Smith 11403d4c4710SBarry Smith #undef __FUNCT__ 1141b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 1142c96a6f78SLois Curfman McInnes /*@ 1143b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1144c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1145c96a6f78SLois Curfman McInnes 1146c7afd0dbSLois Curfman McInnes Not Collective 1147c7afd0dbSLois Curfman McInnes 1148c96a6f78SLois Curfman McInnes Input Parameter: 1149c96a6f78SLois Curfman McInnes . snes - SNES context 1150c96a6f78SLois Curfman McInnes 1151c96a6f78SLois Curfman McInnes Output Parameter: 1152c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1153c96a6f78SLois Curfman McInnes 1154c96a6f78SLois Curfman McInnes Notes: 1155c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1156c96a6f78SLois Curfman McInnes 115736851e7fSLois Curfman McInnes Level: intermediate 115836851e7fSLois Curfman McInnes 1159c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 11602b668275SBarry Smith 11618c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 1162c96a6f78SLois Curfman McInnes @*/ 11637087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 1164c96a6f78SLois Curfman McInnes { 11653a40ed3dSBarry Smith PetscFunctionBegin; 11660700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11674482741eSBarry Smith PetscValidIntPointer(lits,2); 1168c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 11693a40ed3dSBarry Smith PetscFunctionReturn(0); 1170c96a6f78SLois Curfman McInnes } 1171c96a6f78SLois Curfman McInnes 11724a2ae208SSatish Balay #undef __FUNCT__ 117394b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 117452baeb72SSatish Balay /*@ 117594b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 11769b94acceSBarry Smith 117794b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 1178c7afd0dbSLois Curfman McInnes 11799b94acceSBarry Smith Input Parameter: 11809b94acceSBarry Smith . snes - the SNES context 11819b94acceSBarry Smith 11829b94acceSBarry Smith Output Parameter: 118394b7f48cSBarry Smith . ksp - the KSP context 11849b94acceSBarry Smith 11859b94acceSBarry Smith Notes: 118694b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 11879b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 11882999313aSBarry Smith PC contexts as well. 11899b94acceSBarry Smith 119036851e7fSLois Curfman McInnes Level: beginner 119136851e7fSLois Curfman McInnes 119294b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 11939b94acceSBarry Smith 11942999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 11959b94acceSBarry Smith @*/ 11967087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 11979b94acceSBarry Smith { 11981cee3971SBarry Smith PetscErrorCode ierr; 11991cee3971SBarry Smith 12003a40ed3dSBarry Smith PetscFunctionBegin; 12010700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12024482741eSBarry Smith PetscValidPointer(ksp,2); 12031cee3971SBarry Smith 12041cee3971SBarry Smith if (!snes->ksp) { 12051cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 12061cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 12071cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 12081cee3971SBarry Smith } 120994b7f48cSBarry Smith *ksp = snes->ksp; 12103a40ed3dSBarry Smith PetscFunctionReturn(0); 12119b94acceSBarry Smith } 121282bf6240SBarry Smith 12134a2ae208SSatish Balay #undef __FUNCT__ 12142999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 12152999313aSBarry Smith /*@ 12162999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 12172999313aSBarry Smith 12182999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 12192999313aSBarry Smith 12202999313aSBarry Smith Input Parameters: 12212999313aSBarry Smith + snes - the SNES context 12222999313aSBarry Smith - ksp - the KSP context 12232999313aSBarry Smith 12242999313aSBarry Smith Notes: 12252999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 12262999313aSBarry Smith so this routine is rarely needed. 12272999313aSBarry Smith 12282999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 12292999313aSBarry Smith decreased by one. 12302999313aSBarry Smith 12312999313aSBarry Smith Level: developer 12322999313aSBarry Smith 12332999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 12342999313aSBarry Smith 12352999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 12362999313aSBarry Smith @*/ 12377087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 12382999313aSBarry Smith { 12392999313aSBarry Smith PetscErrorCode ierr; 12402999313aSBarry Smith 12412999313aSBarry Smith PetscFunctionBegin; 12420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12430700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 12442999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 12457dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1246906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 12472999313aSBarry Smith snes->ksp = ksp; 12482999313aSBarry Smith PetscFunctionReturn(0); 12492999313aSBarry Smith } 12502999313aSBarry Smith 12517adad957SLisandro Dalcin #if 0 12522999313aSBarry Smith #undef __FUNCT__ 12534a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 12546849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1255e24b481bSBarry Smith { 1256e24b481bSBarry Smith PetscFunctionBegin; 1257e24b481bSBarry Smith PetscFunctionReturn(0); 1258e24b481bSBarry Smith } 12597adad957SLisandro Dalcin #endif 1260e24b481bSBarry Smith 12619b94acceSBarry Smith /* -----------------------------------------------------------*/ 12624a2ae208SSatish Balay #undef __FUNCT__ 12634a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 126452baeb72SSatish Balay /*@ 12659b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 12669b94acceSBarry Smith 1267c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1268c7afd0dbSLois Curfman McInnes 1269c7afd0dbSLois Curfman McInnes Input Parameters: 1270906ed7ccSBarry Smith . comm - MPI communicator 12719b94acceSBarry Smith 12729b94acceSBarry Smith Output Parameter: 12739b94acceSBarry Smith . outsnes - the new SNES context 12749b94acceSBarry Smith 1275c7afd0dbSLois Curfman McInnes Options Database Keys: 1276c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1277c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1278c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1279c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1280c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1281c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1282c1f60f51SBarry Smith 128336851e7fSLois Curfman McInnes Level: beginner 128436851e7fSLois Curfman McInnes 12859b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 12869b94acceSBarry Smith 1287a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1288a8054027SBarry Smith 12899b94acceSBarry Smith @*/ 12907087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 12919b94acceSBarry Smith { 1292dfbe8321SBarry Smith PetscErrorCode ierr; 12939b94acceSBarry Smith SNES snes; 1294fa9f3622SBarry Smith SNESKSPEW *kctx; 129537fcc0dbSBarry Smith 12963a40ed3dSBarry Smith PetscFunctionBegin; 1297ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 12988ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 12998ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 13008ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 13018ba1e511SMatthew Knepley #endif 13028ba1e511SMatthew Knepley 13033194b578SJed Brown ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 13047adad957SLisandro Dalcin 130585385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 13062c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 130788976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 13089b94acceSBarry Smith snes->max_its = 50; 13099750a799SBarry Smith snes->max_funcs = 10000; 13109b94acceSBarry Smith snes->norm = 0.0; 1311b4874afaSBarry Smith snes->rtol = 1.e-8; 1312b4874afaSBarry Smith snes->ttol = 0.0; 131370441072SBarry Smith snes->abstol = 1.e-50; 1314c60f73f4SPeter Brune snes->stol = 1.e-8; 13154b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 13169b94acceSBarry Smith snes->nfuncs = 0; 131750ffb88aSMatthew Knepley snes->numFailures = 0; 131850ffb88aSMatthew Knepley snes->maxFailures = 1; 13197a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1320e35cf81dSBarry Smith snes->lagjacobian = 1; 1321a8054027SBarry Smith snes->lagpreconditioner = 1; 1322639f9d9dSBarry Smith snes->numbermonitors = 0; 13239b94acceSBarry Smith snes->data = 0; 13244dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1325186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 13266f24a144SLois Curfman McInnes snes->nwork = 0; 132758c9b817SLisandro Dalcin snes->work = 0; 132858c9b817SLisandro Dalcin snes->nvwork = 0; 132958c9b817SLisandro Dalcin snes->vwork = 0; 1330758f92a0SBarry Smith snes->conv_hist_len = 0; 1331758f92a0SBarry Smith snes->conv_hist_max = 0; 1332758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1333758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1334758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1335e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1336e4ed7901SPeter Brune snes->norm_init = 0.; 1337e4ed7901SPeter Brune snes->norm_init_set = PETSC_FALSE; 1338184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 133989b92e6fSPeter Brune snes->gssweeps = 1; 13409b94acceSBarry Smith 13413d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 13423d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 13433d4c4710SBarry Smith 13449b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 134538f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 13469b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 13479b94acceSBarry Smith kctx->version = 2; 13489b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 13499b94acceSBarry Smith this was too large for some test cases */ 135075567043SBarry Smith kctx->rtol_last = 0.0; 13519b94acceSBarry Smith kctx->rtol_max = .9; 13529b94acceSBarry Smith kctx->gamma = 1.0; 135362d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 135471f87433Sdalcinl kctx->alpha2 = kctx->alpha; 13559b94acceSBarry Smith kctx->threshold = .1; 135675567043SBarry Smith kctx->lresid_last = 0.0; 135775567043SBarry Smith kctx->norm_last = 0.0; 13589b94acceSBarry Smith 13599b94acceSBarry Smith *outsnes = snes; 13603a40ed3dSBarry Smith PetscFunctionReturn(0); 13619b94acceSBarry Smith } 13629b94acceSBarry Smith 13634a2ae208SSatish Balay #undef __FUNCT__ 13644a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 13659b94acceSBarry Smith /*@C 13669b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 13679b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 13689b94acceSBarry Smith equations. 13699b94acceSBarry Smith 13703f9fe445SBarry Smith Logically Collective on SNES 1371fee21e36SBarry Smith 1372c7afd0dbSLois Curfman McInnes Input Parameters: 1373c7afd0dbSLois Curfman McInnes + snes - the SNES context 1374c7afd0dbSLois Curfman McInnes . r - vector to store function value 1375de044059SHong Zhang . func - function evaluation routine 1376c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1377c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 13789b94acceSBarry Smith 1379c7afd0dbSLois Curfman McInnes Calling sequence of func: 13808d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1381c7afd0dbSLois Curfman McInnes 1382c586c404SJed Brown + snes - the SNES context 1383c586c404SJed Brown . x - state at which to evaluate residual 1384c586c404SJed Brown . f - vector to put residual 1385c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 13869b94acceSBarry Smith 13879b94acceSBarry Smith Notes: 13889b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 13899b94acceSBarry Smith $ f'(x) x = -f(x), 1390c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 13919b94acceSBarry Smith 139236851e7fSLois Curfman McInnes Level: beginner 139336851e7fSLois Curfman McInnes 13949b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 13959b94acceSBarry Smith 13968b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard() 13979b94acceSBarry Smith @*/ 13987087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 13999b94acceSBarry Smith { 140085385478SLisandro Dalcin PetscErrorCode ierr; 14016cab3a1bSJed Brown DM dm; 14026cab3a1bSJed Brown 14033a40ed3dSBarry Smith PetscFunctionBegin; 14040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1405d2a683ecSLisandro Dalcin if (r) { 1406d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1407d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 140885385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 14096bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 141085385478SLisandro Dalcin snes->vec_func = r; 1411d2a683ecSLisandro Dalcin } 14126cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 14136cab3a1bSJed Brown ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr); 14143a40ed3dSBarry Smith PetscFunctionReturn(0); 14159b94acceSBarry Smith } 14169b94acceSBarry Smith 1417646217ecSPeter Brune 1418646217ecSPeter Brune #undef __FUNCT__ 1419e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction" 1420e4ed7901SPeter Brune /*@C 1421e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1422e4ed7901SPeter Brune function norm at the initialization of the method. In some 1423e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1424e4ed7901SPeter Brune SNESSolve. This function allows one to avoid a redundant call 1425e4ed7901SPeter Brune to SNESComputeFunction in that case. 1426e4ed7901SPeter Brune 1427e4ed7901SPeter Brune Logically Collective on SNES 1428e4ed7901SPeter Brune 1429e4ed7901SPeter Brune Input Parameters: 1430e4ed7901SPeter Brune + snes - the SNES context 1431e4ed7901SPeter Brune - f - vector to store function value 1432e4ed7901SPeter Brune 1433e4ed7901SPeter Brune Notes: 1434e4ed7901SPeter Brune This should not be modified during the solution procedure. 1435e4ed7901SPeter Brune 1436e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1437e4ed7901SPeter Brune 1438e4ed7901SPeter Brune Level: developer 1439e4ed7901SPeter Brune 1440e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function 1441e4ed7901SPeter Brune 1442e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm() 1443e4ed7901SPeter Brune @*/ 1444e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1445e4ed7901SPeter Brune { 1446e4ed7901SPeter Brune PetscErrorCode ierr; 1447e4ed7901SPeter Brune Vec vec_func; 1448e4ed7901SPeter Brune 1449e4ed7901SPeter Brune PetscFunctionBegin; 1450e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1451e4ed7901SPeter Brune PetscValidHeaderSpecific(f,VEC_CLASSID,2); 1452e4ed7901SPeter Brune PetscCheckSameComm(snes,1,f,2); 1453e4ed7901SPeter Brune ierr = PetscObjectReference((PetscObject)f);CHKERRQ(ierr); 1454e4ed7901SPeter Brune ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1455e4ed7901SPeter Brune ierr = VecCopy(f, vec_func);CHKERRQ(ierr); 1456*217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 1457e4ed7901SPeter Brune PetscFunctionReturn(0); 1458e4ed7901SPeter Brune } 1459e4ed7901SPeter Brune 1460e4ed7901SPeter Brune 1461e4ed7901SPeter Brune #undef __FUNCT__ 1462e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm" 1463e4ed7901SPeter Brune /*@C 1464e4ed7901SPeter Brune SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm 1465e4ed7901SPeter Brune at the initialization of the method. In some instances, the user has precomputed 1466e4ed7901SPeter Brune the function and its norm before calling SNESSolve. This function allows one to 1467e4ed7901SPeter Brune avoid a redundant call to SNESComputeFunction() and VecNorm() in that case. 1468e4ed7901SPeter Brune 1469e4ed7901SPeter Brune Logically Collective on SNES 1470e4ed7901SPeter Brune 1471e4ed7901SPeter Brune Input Parameters: 1472e4ed7901SPeter Brune + snes - the SNES context 1473e4ed7901SPeter Brune - fnorm - the norm of F as set by SNESSetInitialFunction() 1474e4ed7901SPeter Brune 1475e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1476e4ed7901SPeter Brune 1477e4ed7901SPeter Brune Level: developer 1478e4ed7901SPeter Brune 1479e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm 1480e4ed7901SPeter Brune 1481e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction() 1482e4ed7901SPeter Brune @*/ 1483e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm) 1484e4ed7901SPeter Brune { 1485e4ed7901SPeter Brune PetscFunctionBegin; 1486e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1487e4ed7901SPeter Brune snes->norm_init = fnorm; 1488e4ed7901SPeter Brune snes->norm_init_set = PETSC_TRUE; 1489e4ed7901SPeter Brune PetscFunctionReturn(0); 1490e4ed7901SPeter Brune } 1491e4ed7901SPeter Brune 1492e4ed7901SPeter Brune #undef __FUNCT__ 1493646217ecSPeter Brune #define __FUNCT__ "SNESSetGS" 1494c79ef259SPeter Brune /*@C 1495c79ef259SPeter Brune SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for 1496c79ef259SPeter Brune use with composed nonlinear solvers. 1497c79ef259SPeter Brune 1498c79ef259SPeter Brune Input Parameters: 1499c79ef259SPeter Brune + snes - the SNES context 1500c79ef259SPeter Brune . gsfunc - function evaluation routine 1501c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 1502c79ef259SPeter Brune smoother evaluation routine (may be PETSC_NULL) 1503c79ef259SPeter Brune 1504c79ef259SPeter Brune Calling sequence of func: 1505c79ef259SPeter Brune $ func (SNES snes,Vec x,Vec b,void *ctx); 1506c79ef259SPeter Brune 1507c79ef259SPeter Brune + X - solution vector 1508c79ef259SPeter Brune . B - RHS vector 1509d28543b3SPeter Brune - ctx - optional user-defined Gauss-Seidel context 1510c79ef259SPeter Brune 1511c79ef259SPeter Brune Notes: 1512c79ef259SPeter Brune The GS routines are used by the composed nonlinear solver to generate 1513c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1514c79ef259SPeter Brune 1515d28543b3SPeter Brune Level: intermediate 1516c79ef259SPeter Brune 1517d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1518c79ef259SPeter Brune 1519c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS() 1520c79ef259SPeter Brune @*/ 15216cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx) 15226cab3a1bSJed Brown { 15236cab3a1bSJed Brown PetscErrorCode ierr; 15246cab3a1bSJed Brown DM dm; 15256cab3a1bSJed Brown 1526646217ecSPeter Brune PetscFunctionBegin; 15276cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15286cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 15296cab3a1bSJed Brown ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr); 1530646217ecSPeter Brune PetscFunctionReturn(0); 1531646217ecSPeter Brune } 1532646217ecSPeter Brune 1533d25893d9SBarry Smith #undef __FUNCT__ 153489b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps" 153589b92e6fSPeter Brune /*@ 153689b92e6fSPeter Brune SNESSetGSSweeps - Sets the number of sweeps of GS to use. 153789b92e6fSPeter Brune 153889b92e6fSPeter Brune Input Parameters: 153989b92e6fSPeter Brune + snes - the SNES context 154089b92e6fSPeter Brune - sweeps - the number of sweeps of GS to perform. 154189b92e6fSPeter Brune 154289b92e6fSPeter Brune Level: intermediate 154389b92e6fSPeter Brune 154489b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 154589b92e6fSPeter Brune 154689b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps() 154789b92e6fSPeter Brune @*/ 154889b92e6fSPeter Brune 154989b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) { 155089b92e6fSPeter Brune PetscFunctionBegin; 155189b92e6fSPeter Brune snes->gssweeps = sweeps; 155289b92e6fSPeter Brune PetscFunctionReturn(0); 155389b92e6fSPeter Brune } 155489b92e6fSPeter Brune 155589b92e6fSPeter Brune 155689b92e6fSPeter Brune #undef __FUNCT__ 155789b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps" 155889b92e6fSPeter Brune /*@ 155989b92e6fSPeter Brune SNESGetGSSweeps - Gets the number of sweeps GS will use. 156089b92e6fSPeter Brune 156189b92e6fSPeter Brune Input Parameters: 156289b92e6fSPeter Brune . snes - the SNES context 156389b92e6fSPeter Brune 156489b92e6fSPeter Brune Output Parameters: 156589b92e6fSPeter Brune . sweeps - the number of sweeps of GS to perform. 156689b92e6fSPeter Brune 156789b92e6fSPeter Brune Level: intermediate 156889b92e6fSPeter Brune 156989b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 157089b92e6fSPeter Brune 157189b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps() 157289b92e6fSPeter Brune @*/ 157389b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) { 157489b92e6fSPeter Brune PetscFunctionBegin; 157589b92e6fSPeter Brune *sweeps = snes->gssweeps; 157689b92e6fSPeter Brune PetscFunctionReturn(0); 157789b92e6fSPeter Brune } 157889b92e6fSPeter Brune 157989b92e6fSPeter Brune #undef __FUNCT__ 15808b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 15818b0a5094SBarry Smith PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 15828b0a5094SBarry Smith { 15838b0a5094SBarry Smith PetscErrorCode ierr; 15846cab3a1bSJed Brown void *functx,*jacctx; 15856cab3a1bSJed Brown 15868b0a5094SBarry Smith PetscFunctionBegin; 15876cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 15886cab3a1bSJed Brown ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr); 15898b0a5094SBarry Smith /* A(x)*x - b(x) */ 15906cab3a1bSJed Brown ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr); 15916cab3a1bSJed Brown ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr); 15928b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 15938b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 15948b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 15958b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 15968b0a5094SBarry Smith PetscFunctionReturn(0); 15978b0a5094SBarry Smith } 15988b0a5094SBarry Smith 15998b0a5094SBarry Smith #undef __FUNCT__ 16008b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 16018b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 16028b0a5094SBarry Smith { 16038b0a5094SBarry Smith PetscFunctionBegin; 16048b0a5094SBarry Smith *flag = snes->matstruct; 16058b0a5094SBarry Smith PetscFunctionReturn(0); 16068b0a5094SBarry Smith } 16078b0a5094SBarry Smith 16088b0a5094SBarry Smith #undef __FUNCT__ 16098b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 16108b0a5094SBarry Smith /*@C 16110d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 16128b0a5094SBarry Smith 16138b0a5094SBarry Smith Logically Collective on SNES 16148b0a5094SBarry Smith 16158b0a5094SBarry Smith Input Parameters: 16168b0a5094SBarry Smith + snes - the SNES context 16178b0a5094SBarry Smith . r - vector to store function value 16188b0a5094SBarry Smith . func - function evaluation routine 16198b0a5094SBarry 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) 16208b0a5094SBarry Smith . mat - matrix to store A 16218b0a5094SBarry Smith . mfunc - function to compute matrix value 16228b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 16238b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 16248b0a5094SBarry Smith 16258b0a5094SBarry Smith Calling sequence of func: 16268b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 16278b0a5094SBarry Smith 16288b0a5094SBarry Smith + f - function vector 16298b0a5094SBarry Smith - ctx - optional user-defined function context 16308b0a5094SBarry Smith 16318b0a5094SBarry Smith Calling sequence of mfunc: 16328b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 16338b0a5094SBarry Smith 16348b0a5094SBarry Smith + x - input vector 16358b0a5094SBarry 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(), 16368b0a5094SBarry Smith normally just pass mat in this location 16378b0a5094SBarry Smith . mat - form A(x) matrix 16388b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 16398b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 16408b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 16418b0a5094SBarry Smith 16428b0a5094SBarry Smith Notes: 16438b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 16448b0a5094SBarry Smith 16458b0a5094SBarry 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} 16468b0a5094SBarry 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. 16478b0a5094SBarry Smith 16488b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 16498b0a5094SBarry Smith 16500d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 16510d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 16528b0a5094SBarry Smith 16538b0a5094SBarry 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 16548b0a5094SBarry 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 16558b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 16568b0a5094SBarry Smith 16578b0a5094SBarry Smith Level: beginner 16588b0a5094SBarry Smith 16598b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 16608b0a5094SBarry Smith 16610d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard() 16628b0a5094SBarry Smith @*/ 16638b0a5094SBarry 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) 16648b0a5094SBarry Smith { 16658b0a5094SBarry Smith PetscErrorCode ierr; 16668b0a5094SBarry Smith PetscFunctionBegin; 16678b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16688b0a5094SBarry Smith snes->ops->computepfunction = func; 16698b0a5094SBarry Smith snes->ops->computepjacobian = mfunc; 16708b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 16718b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 16728b0a5094SBarry Smith PetscFunctionReturn(0); 16738b0a5094SBarry Smith } 16748b0a5094SBarry Smith 16758b0a5094SBarry Smith #undef __FUNCT__ 1676d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1677d25893d9SBarry Smith /*@C 1678d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1679d25893d9SBarry Smith 1680d25893d9SBarry Smith Logically Collective on SNES 1681d25893d9SBarry Smith 1682d25893d9SBarry Smith Input Parameters: 1683d25893d9SBarry Smith + snes - the SNES context 1684d25893d9SBarry Smith . func - function evaluation routine 1685d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1686d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1687d25893d9SBarry Smith 1688d25893d9SBarry Smith Calling sequence of func: 1689d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1690d25893d9SBarry Smith 1691d25893d9SBarry Smith . f - function vector 1692d25893d9SBarry Smith - ctx - optional user-defined function context 1693d25893d9SBarry Smith 1694d25893d9SBarry Smith Level: intermediate 1695d25893d9SBarry Smith 1696d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1697d25893d9SBarry Smith 1698d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1699d25893d9SBarry Smith @*/ 1700d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1701d25893d9SBarry Smith { 1702d25893d9SBarry Smith PetscFunctionBegin; 1703d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1704d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1705d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1706d25893d9SBarry Smith PetscFunctionReturn(0); 1707d25893d9SBarry Smith } 1708d25893d9SBarry Smith 17093ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 17103ab0aad5SBarry Smith #undef __FUNCT__ 17111096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 17121096aae1SMatthew Knepley /*@C 17131096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 17141096aae1SMatthew Knepley it assumes a zero right hand side. 17151096aae1SMatthew Knepley 17163f9fe445SBarry Smith Logically Collective on SNES 17171096aae1SMatthew Knepley 17181096aae1SMatthew Knepley Input Parameter: 17191096aae1SMatthew Knepley . snes - the SNES context 17201096aae1SMatthew Knepley 17211096aae1SMatthew Knepley Output Parameter: 1722bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 17231096aae1SMatthew Knepley 17241096aae1SMatthew Knepley Level: intermediate 17251096aae1SMatthew Knepley 17261096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 17271096aae1SMatthew Knepley 172885385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 17291096aae1SMatthew Knepley @*/ 17307087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 17311096aae1SMatthew Knepley { 17321096aae1SMatthew Knepley PetscFunctionBegin; 17330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 17341096aae1SMatthew Knepley PetscValidPointer(rhs,2); 173585385478SLisandro Dalcin *rhs = snes->vec_rhs; 17361096aae1SMatthew Knepley PetscFunctionReturn(0); 17371096aae1SMatthew Knepley } 17381096aae1SMatthew Knepley 17391096aae1SMatthew Knepley #undef __FUNCT__ 17404a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 17419b94acceSBarry Smith /*@ 174236851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 17439b94acceSBarry Smith SNESSetFunction(). 17449b94acceSBarry Smith 1745c7afd0dbSLois Curfman McInnes Collective on SNES 1746c7afd0dbSLois Curfman McInnes 17479b94acceSBarry Smith Input Parameters: 1748c7afd0dbSLois Curfman McInnes + snes - the SNES context 1749c7afd0dbSLois Curfman McInnes - x - input vector 17509b94acceSBarry Smith 17519b94acceSBarry Smith Output Parameter: 17523638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 17539b94acceSBarry Smith 17541bffabb2SLois Curfman McInnes Notes: 175536851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 175636851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 175736851e7fSLois Curfman McInnes themselves. 175836851e7fSLois Curfman McInnes 175936851e7fSLois Curfman McInnes Level: developer 176036851e7fSLois Curfman McInnes 17619b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 17629b94acceSBarry Smith 1763a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 17649b94acceSBarry Smith @*/ 17657087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 17669b94acceSBarry Smith { 1767dfbe8321SBarry Smith PetscErrorCode ierr; 17686cab3a1bSJed Brown DM dm; 17696cab3a1bSJed Brown SNESDM sdm; 17709b94acceSBarry Smith 17713a40ed3dSBarry Smith PetscFunctionBegin; 17720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 17730700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 17740700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1775c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1776c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 17774ec14c9cSBarry Smith VecValidValues(x,2,PETSC_TRUE); 1778184914b5SBarry Smith 17796cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 17806cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 1781d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 17826cab3a1bSJed Brown if (sdm->computefunction) { 1783d64ed03dSBarry Smith PetscStackPush("SNES user function"); 17846cab3a1bSJed Brown ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 1785d64ed03dSBarry Smith PetscStackPop; 178673250ac0SBarry Smith } else if (snes->dm) { 1787644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1788c90fad12SPeter Brune } else if (snes->vec_rhs) { 1789c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1790644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 179185385478SLisandro Dalcin if (snes->vec_rhs) { 179285385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 17933ab0aad5SBarry Smith } 1794ae3c334cSLois Curfman McInnes snes->nfuncs++; 1795d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 17964ec14c9cSBarry Smith VecValidValues(y,3,PETSC_FALSE); 17973a40ed3dSBarry Smith PetscFunctionReturn(0); 17989b94acceSBarry Smith } 17999b94acceSBarry Smith 18004a2ae208SSatish Balay #undef __FUNCT__ 1801646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1802c79ef259SPeter Brune /*@ 1803c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1804c79ef259SPeter Brune SNESSetGS(). 1805c79ef259SPeter Brune 1806c79ef259SPeter Brune Collective on SNES 1807c79ef259SPeter Brune 1808c79ef259SPeter Brune Input Parameters: 1809c79ef259SPeter Brune + snes - the SNES context 1810c79ef259SPeter Brune . x - input vector 1811c79ef259SPeter Brune - b - rhs vector 1812c79ef259SPeter Brune 1813c79ef259SPeter Brune Output Parameter: 1814c79ef259SPeter Brune . x - new solution vector 1815c79ef259SPeter Brune 1816c79ef259SPeter Brune Notes: 1817c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1818c79ef259SPeter Brune implementations, so most users would not generally call this routine 1819c79ef259SPeter Brune themselves. 1820c79ef259SPeter Brune 1821c79ef259SPeter Brune Level: developer 1822c79ef259SPeter Brune 1823c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1824c79ef259SPeter Brune 1825c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1826c79ef259SPeter Brune @*/ 1827646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1828646217ecSPeter Brune { 1829646217ecSPeter Brune PetscErrorCode ierr; 183089b92e6fSPeter Brune PetscInt i; 18316cab3a1bSJed Brown DM dm; 18326cab3a1bSJed Brown SNESDM sdm; 1833646217ecSPeter Brune 1834646217ecSPeter Brune PetscFunctionBegin; 1835646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1836646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1837646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1838646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 1839646217ecSPeter Brune if(b) PetscCheckSameComm(snes,1,b,3); 18404ec14c9cSBarry Smith if (b) VecValidValues(b,2,PETSC_TRUE); 1841701cf23dSPeter Brune ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 18426cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18436cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 18446cab3a1bSJed Brown if (sdm->computegs) { 184589b92e6fSPeter Brune for (i = 0; i < snes->gssweeps; i++) { 1846646217ecSPeter Brune PetscStackPush("SNES user GS"); 18476cab3a1bSJed Brown ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 1848646217ecSPeter Brune PetscStackPop; 184989b92e6fSPeter Brune } 1850646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 1851701cf23dSPeter Brune ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 18524ec14c9cSBarry Smith VecValidValues(x,3,PETSC_FALSE); 1853646217ecSPeter Brune PetscFunctionReturn(0); 1854646217ecSPeter Brune } 1855646217ecSPeter Brune 1856646217ecSPeter Brune 1857646217ecSPeter Brune #undef __FUNCT__ 18584a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 185962fef451SLois Curfman McInnes /*@ 186062fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 186162fef451SLois Curfman McInnes set with SNESSetJacobian(). 186262fef451SLois Curfman McInnes 1863c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1864c7afd0dbSLois Curfman McInnes 186562fef451SLois Curfman McInnes Input Parameters: 1866c7afd0dbSLois Curfman McInnes + snes - the SNES context 1867c7afd0dbSLois Curfman McInnes - x - input vector 186862fef451SLois Curfman McInnes 186962fef451SLois Curfman McInnes Output Parameters: 1870c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 187162fef451SLois Curfman McInnes . B - optional preconditioning matrix 18722b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1873fee21e36SBarry Smith 1874e35cf81dSBarry Smith Options Database Keys: 1875e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1876693365a8SJed Brown . -snes_lag_jacobian <lag> 1877693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1878693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1879693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 18804c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1881c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 1882c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 1883c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 1884c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 1885c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 18864c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 1887c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 1888c01495d3SJed Brown 1889e35cf81dSBarry Smith 189062fef451SLois Curfman McInnes Notes: 189162fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 189262fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 189362fef451SLois Curfman McInnes 189494b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1895dc5a77f8SLois Curfman McInnes flag parameter. 189662fef451SLois Curfman McInnes 189736851e7fSLois Curfman McInnes Level: developer 189836851e7fSLois Curfman McInnes 189962fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 190062fef451SLois Curfman McInnes 1901e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 190262fef451SLois Curfman McInnes @*/ 19037087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 19049b94acceSBarry Smith { 1905dfbe8321SBarry Smith PetscErrorCode ierr; 1906ace3abfcSBarry Smith PetscBool flag; 19076cab3a1bSJed Brown DM dm; 19086cab3a1bSJed Brown SNESDM sdm; 19093a40ed3dSBarry Smith 19103a40ed3dSBarry Smith PetscFunctionBegin; 19110700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 19120700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 19134482741eSBarry Smith PetscValidPointer(flg,5); 1914c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 19154ec14c9cSBarry Smith VecValidValues(X,2,PETSC_TRUE); 19166cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 19176cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 19186cab3a1bSJed Brown if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 1919ebd3b9afSBarry Smith 1920ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1921ebd3b9afSBarry Smith 1922fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 1923fe3ffe1eSBarry Smith snes->lagjacobian = -1; 1924fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1925fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 1926e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1927e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1928ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1929ebd3b9afSBarry Smith if (flag) { 1930ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1931ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1932ebd3b9afSBarry Smith } 1933e35cf81dSBarry Smith PetscFunctionReturn(0); 1934e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1935e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1936e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1937ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1938ebd3b9afSBarry Smith if (flag) { 1939ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1940ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1941ebd3b9afSBarry Smith } 1942e35cf81dSBarry Smith PetscFunctionReturn(0); 1943e35cf81dSBarry Smith } 1944e35cf81dSBarry Smith 1945c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 1946e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1947d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 19486cab3a1bSJed Brown ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr); 1949d64ed03dSBarry Smith PetscStackPop; 1950d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1951a8054027SBarry Smith 19523b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 19533b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 19543b4f5425SBarry Smith snes->lagpreconditioner = -1; 19553b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 1956a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1957a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 1958a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 1959a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1960a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 1961a8054027SBarry Smith } 1962a8054027SBarry Smith 19636d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 19640700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 19650700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 1966693365a8SJed Brown { 1967693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 1968693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 1969693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 1970693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 1971693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 1972693365a8SJed Brown if (flag || flag_draw || flag_contour) { 1973693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 1974693365a8SJed Brown MatStructure mstruct; 1975693365a8SJed Brown PetscViewer vdraw,vstdout; 19766b3a5b13SJed Brown PetscBool flg; 1977693365a8SJed Brown if (flag_operator) { 1978693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 1979693365a8SJed Brown Bexp = Bexp_mine; 1980693365a8SJed Brown } else { 1981693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 1982693365a8SJed Brown ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 1983693365a8SJed Brown if (flg) Bexp = *B; 1984693365a8SJed Brown else { 1985693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 1986693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 1987693365a8SJed Brown Bexp = Bexp_mine; 1988693365a8SJed Brown } 1989693365a8SJed Brown } 1990693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 1991693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 1992693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 1993693365a8SJed Brown if (flag_draw || flag_contour) { 1994693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 1995693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 1996693365a8SJed Brown } else vdraw = PETSC_NULL; 1997693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 1998693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 1999693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 2000693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 2001693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2002693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 2003693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2004693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 2005693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2006693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 2007693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2008693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 2009693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2010693365a8SJed Brown } 2011693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2012693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2013693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 2014693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 2015693365a8SJed Brown } 2016693365a8SJed Brown } 20174c30e9fbSJed Brown { 20186719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 20196719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 20204c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 20216719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 20224c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 20234c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 20246719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 20256719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 20266719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 20276719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 20284c30e9fbSJed Brown Mat Bfd; 20294c30e9fbSJed Brown MatStructure mstruct; 20304c30e9fbSJed Brown PetscViewer vdraw,vstdout; 20314c30e9fbSJed Brown ISColoring iscoloring; 20324c30e9fbSJed Brown MatFDColoring matfdcoloring; 20334c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 20344c30e9fbSJed Brown void *funcctx; 20356719d8e4SJed Brown PetscReal norm1,norm2,normmax; 20364c30e9fbSJed Brown 20374c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 20384c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 20394c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 20404c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 20414c30e9fbSJed Brown 20424c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 20434c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 20444c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 20454c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 20464c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 20474c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 20484c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 20494c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 20504c30e9fbSJed Brown 20514c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 20524c30e9fbSJed Brown if (flag_draw || flag_contour) { 20534c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 20544c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 20554c30e9fbSJed Brown } else vdraw = PETSC_NULL; 20564c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 20576719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 20584c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 20594c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 20606719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 20614c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 20624c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 20634c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 20646719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 20654c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 20666719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 20676719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 20684c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 20694c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 20704c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 20714c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 20724c30e9fbSJed Brown } 20734c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 20746719d8e4SJed Brown 20756719d8e4SJed Brown if (flag_threshold) { 20766719d8e4SJed Brown PetscInt bs,rstart,rend,i; 20776719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 20786719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 20796719d8e4SJed Brown for (i=rstart; i<rend; i++) { 20806719d8e4SJed Brown const PetscScalar *ba,*ca; 20816719d8e4SJed Brown const PetscInt *bj,*cj; 20826719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 20836719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 20846719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 20856719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 20866719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 20876719d8e4SJed Brown for (j=0; j<bn; j++) { 20886719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 20896719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 20906719d8e4SJed Brown maxentrycol = bj[j]; 20916719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 20926719d8e4SJed Brown } 20936719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 20946719d8e4SJed Brown maxdiffcol = bj[j]; 20956719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 20966719d8e4SJed Brown } 20976719d8e4SJed Brown if (rdiff > maxrdiff) { 20986719d8e4SJed Brown maxrdiffcol = bj[j]; 20996719d8e4SJed Brown maxrdiff = rdiff; 21006719d8e4SJed Brown } 21016719d8e4SJed Brown } 21026719d8e4SJed Brown if (maxrdiff > 1) { 21036719d8e4SJed 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); 21046719d8e4SJed Brown for (j=0; j<bn; j++) { 21056719d8e4SJed Brown PetscReal rdiff; 21066719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 21076719d8e4SJed Brown if (rdiff > 1) { 21086719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 21096719d8e4SJed Brown } 21106719d8e4SJed Brown } 21116719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 21126719d8e4SJed Brown } 21136719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 21146719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 21156719d8e4SJed Brown } 21166719d8e4SJed Brown } 21174c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 21184c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 21194c30e9fbSJed Brown } 21204c30e9fbSJed Brown } 21213a40ed3dSBarry Smith PetscFunctionReturn(0); 21229b94acceSBarry Smith } 21239b94acceSBarry Smith 21244a2ae208SSatish Balay #undef __FUNCT__ 21254a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 21269b94acceSBarry Smith /*@C 21279b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2128044dda88SLois Curfman McInnes location to store the matrix. 21299b94acceSBarry Smith 21303f9fe445SBarry Smith Logically Collective on SNES and Mat 2131c7afd0dbSLois Curfman McInnes 21329b94acceSBarry Smith Input Parameters: 2133c7afd0dbSLois Curfman McInnes + snes - the SNES context 21349b94acceSBarry Smith . A - Jacobian matrix 21359b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 2136efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 2137c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 2138efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 21399b94acceSBarry Smith 21409b94acceSBarry Smith Calling sequence of func: 21418d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 21429b94acceSBarry Smith 2143c7afd0dbSLois Curfman McInnes + x - input vector 21449b94acceSBarry Smith . A - Jacobian matrix 21459b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 2146ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 21472b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 2148c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 21499b94acceSBarry Smith 21509b94acceSBarry Smith Notes: 215194b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 21522cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 2153ac21db08SLois Curfman McInnes 2154ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 21559b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 21569b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 21579b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 21589b94acceSBarry Smith throughout the global iterations. 21599b94acceSBarry Smith 216016913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 216116913363SBarry Smith each matrix. 216216913363SBarry Smith 2163a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 2164a8a26c1eSJed Brown must be a MatFDColoring. 2165a8a26c1eSJed Brown 2166c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2167c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2168c3cc8fd1SJed Brown 216936851e7fSLois Curfman McInnes Level: beginner 217036851e7fSLois Curfman McInnes 21719b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 21729b94acceSBarry Smith 21733ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 21749b94acceSBarry Smith @*/ 21757087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 21769b94acceSBarry Smith { 2177dfbe8321SBarry Smith PetscErrorCode ierr; 21786cab3a1bSJed Brown DM dm; 21793a7fca6bSBarry Smith 21803a40ed3dSBarry Smith PetscFunctionBegin; 21810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 21820700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 21830700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 2184c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 218506975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 21866cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 21876cab3a1bSJed Brown ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr); 21883a7fca6bSBarry Smith if (A) { 21897dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 21906bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 21919b94acceSBarry Smith snes->jacobian = A; 21923a7fca6bSBarry Smith } 21933a7fca6bSBarry Smith if (B) { 21947dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 21956bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 21969b94acceSBarry Smith snes->jacobian_pre = B; 21973a7fca6bSBarry Smith } 21983a40ed3dSBarry Smith PetscFunctionReturn(0); 21999b94acceSBarry Smith } 220062fef451SLois Curfman McInnes 22014a2ae208SSatish Balay #undef __FUNCT__ 22024a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 2203c2aafc4cSSatish Balay /*@C 2204b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2205b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2206b4fd4287SBarry Smith 2207c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2208c7afd0dbSLois Curfman McInnes 2209b4fd4287SBarry Smith Input Parameter: 2210b4fd4287SBarry Smith . snes - the nonlinear solver context 2211b4fd4287SBarry Smith 2212b4fd4287SBarry Smith Output Parameters: 2213c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 2214b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 221570e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 221670e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 2217fee21e36SBarry Smith 221836851e7fSLois Curfman McInnes Level: advanced 221936851e7fSLois Curfman McInnes 2220b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 2221b4fd4287SBarry Smith @*/ 22227087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 2223b4fd4287SBarry Smith { 22246cab3a1bSJed Brown PetscErrorCode ierr; 22256cab3a1bSJed Brown DM dm; 22266cab3a1bSJed Brown SNESDM sdm; 22276cab3a1bSJed Brown 22283a40ed3dSBarry Smith PetscFunctionBegin; 22290700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2230b4fd4287SBarry Smith if (A) *A = snes->jacobian; 2231b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 22326cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 22336cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 22346cab3a1bSJed Brown if (func) *func = sdm->computejacobian; 22356cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 22363a40ed3dSBarry Smith PetscFunctionReturn(0); 2237b4fd4287SBarry Smith } 2238b4fd4287SBarry Smith 22399b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 22409b94acceSBarry Smith 22414a2ae208SSatish Balay #undef __FUNCT__ 22424a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 22439b94acceSBarry Smith /*@ 22449b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2245272ac6f2SLois Curfman McInnes of a nonlinear solver. 22469b94acceSBarry Smith 2247fee21e36SBarry Smith Collective on SNES 2248fee21e36SBarry Smith 2249c7afd0dbSLois Curfman McInnes Input Parameters: 225070e92668SMatthew Knepley . snes - the SNES context 2251c7afd0dbSLois Curfman McInnes 2252272ac6f2SLois Curfman McInnes Notes: 2253272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2254272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2255272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2256272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2257272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2258272ac6f2SLois Curfman McInnes 225936851e7fSLois Curfman McInnes Level: advanced 226036851e7fSLois Curfman McInnes 22619b94acceSBarry Smith .keywords: SNES, nonlinear, setup 22629b94acceSBarry Smith 22639b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 22649b94acceSBarry Smith @*/ 22657087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 22669b94acceSBarry Smith { 2267dfbe8321SBarry Smith PetscErrorCode ierr; 22686cab3a1bSJed Brown DM dm; 22696cab3a1bSJed Brown SNESDM sdm; 22703a40ed3dSBarry Smith 22713a40ed3dSBarry Smith PetscFunctionBegin; 22720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 22734dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 22749b94acceSBarry Smith 22757adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 227685385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 227785385478SLisandro Dalcin } 227885385478SLisandro Dalcin 2279a63bb30eSJed Brown ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 228017186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 228158c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 228258c9b817SLisandro Dalcin 228358c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 228458c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 228558c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 228658c9b817SLisandro Dalcin } 228758c9b817SLisandro Dalcin 22886cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 22896cab3a1bSJed Brown ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */ 22906cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 22916cab3a1bSJed Brown if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc"); 22926cab3a1bSJed Brown if (!snes->vec_func) { 22936cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2294214df951SJed Brown } 2295efd51863SBarry Smith 2296b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 2297b710008aSBarry Smith 2298f1c6b773SPeter Brune if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);} 22999e764e56SPeter Brune 2300d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 2301d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2302d25893d9SBarry Smith } 2303d25893d9SBarry Smith 2304410397dcSLisandro Dalcin if (snes->ops->setup) { 2305410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2306410397dcSLisandro Dalcin } 230758c9b817SLisandro Dalcin 23087aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 23093a40ed3dSBarry Smith PetscFunctionReturn(0); 23109b94acceSBarry Smith } 23119b94acceSBarry Smith 23124a2ae208SSatish Balay #undef __FUNCT__ 231337596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 231437596af1SLisandro Dalcin /*@ 231537596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 231637596af1SLisandro Dalcin 231737596af1SLisandro Dalcin Collective on SNES 231837596af1SLisandro Dalcin 231937596af1SLisandro Dalcin Input Parameter: 232037596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 232137596af1SLisandro Dalcin 2322d25893d9SBarry Smith Level: intermediate 2323d25893d9SBarry Smith 2324d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 232537596af1SLisandro Dalcin 232637596af1SLisandro Dalcin .keywords: SNES, destroy 232737596af1SLisandro Dalcin 232837596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 232937596af1SLisandro Dalcin @*/ 233037596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 233137596af1SLisandro Dalcin { 233237596af1SLisandro Dalcin PetscErrorCode ierr; 233337596af1SLisandro Dalcin 233437596af1SLisandro Dalcin PetscFunctionBegin; 233537596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2336d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2337d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2338d25893d9SBarry Smith snes->user = PETSC_NULL; 2339d25893d9SBarry Smith } 23408a23116dSBarry Smith if (snes->pc) { 23418a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 23428a23116dSBarry Smith } 23438a23116dSBarry Smith 234437596af1SLisandro Dalcin if (snes->ops->reset) { 234537596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 234637596af1SLisandro Dalcin } 23479e764e56SPeter Brune if (snes->ksp) { 23489e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 23499e764e56SPeter Brune } 23509e764e56SPeter Brune 23519e764e56SPeter Brune if (snes->linesearch) { 2352f1c6b773SPeter Brune ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 23539e764e56SPeter Brune } 23549e764e56SPeter Brune 23556bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 23566bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 23576bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 23586bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 23596bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 23606bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2361c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2362c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 236337596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 236437596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 236537596af1SLisandro Dalcin PetscFunctionReturn(0); 236637596af1SLisandro Dalcin } 236737596af1SLisandro Dalcin 236837596af1SLisandro Dalcin #undef __FUNCT__ 23694a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 237052baeb72SSatish Balay /*@ 23719b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 23729b94acceSBarry Smith with SNESCreate(). 23739b94acceSBarry Smith 2374c7afd0dbSLois Curfman McInnes Collective on SNES 2375c7afd0dbSLois Curfman McInnes 23769b94acceSBarry Smith Input Parameter: 23779b94acceSBarry Smith . snes - the SNES context 23789b94acceSBarry Smith 237936851e7fSLois Curfman McInnes Level: beginner 238036851e7fSLois Curfman McInnes 23819b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 23829b94acceSBarry Smith 238363a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 23849b94acceSBarry Smith @*/ 23856bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 23869b94acceSBarry Smith { 23876849ba73SBarry Smith PetscErrorCode ierr; 23883a40ed3dSBarry Smith 23893a40ed3dSBarry Smith PetscFunctionBegin; 23906bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 23916bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 23926bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2393d4bb536fSBarry Smith 23946bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 23958a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 23966b8b9a38SLisandro Dalcin 2397be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 23986bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 23996bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 24006d4c513bSLisandro Dalcin 24016bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 24026bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 2403f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 24046b8b9a38SLisandro Dalcin 24056bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 24066bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 24076bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 24086b8b9a38SLisandro Dalcin } 24096bf464f9SBarry Smith if ((*snes)->conv_malloc) { 24106bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 24116bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 241258c9b817SLisandro Dalcin } 24136bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2414a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 24153a40ed3dSBarry Smith PetscFunctionReturn(0); 24169b94acceSBarry Smith } 24179b94acceSBarry Smith 24189b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 24199b94acceSBarry Smith 24204a2ae208SSatish Balay #undef __FUNCT__ 2421a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2422a8054027SBarry Smith /*@ 2423a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2424a8054027SBarry Smith 24253f9fe445SBarry Smith Logically Collective on SNES 2426a8054027SBarry Smith 2427a8054027SBarry Smith Input Parameters: 2428a8054027SBarry Smith + snes - the SNES context 2429a8054027SBarry 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 24303b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2431a8054027SBarry Smith 2432a8054027SBarry Smith Options Database Keys: 2433a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2434a8054027SBarry Smith 2435a8054027SBarry Smith Notes: 2436a8054027SBarry Smith The default is 1 2437a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2438a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2439a8054027SBarry Smith 2440a8054027SBarry Smith Level: intermediate 2441a8054027SBarry Smith 2442a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2443a8054027SBarry Smith 2444e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2445a8054027SBarry Smith 2446a8054027SBarry Smith @*/ 24477087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2448a8054027SBarry Smith { 2449a8054027SBarry Smith PetscFunctionBegin; 24500700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2451e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2452e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2453c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2454a8054027SBarry Smith snes->lagpreconditioner = lag; 2455a8054027SBarry Smith PetscFunctionReturn(0); 2456a8054027SBarry Smith } 2457a8054027SBarry Smith 2458a8054027SBarry Smith #undef __FUNCT__ 2459efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2460efd51863SBarry Smith /*@ 2461efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2462efd51863SBarry Smith 2463efd51863SBarry Smith Logically Collective on SNES 2464efd51863SBarry Smith 2465efd51863SBarry Smith Input Parameters: 2466efd51863SBarry Smith + snes - the SNES context 2467efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2468efd51863SBarry Smith 2469efd51863SBarry Smith Options Database Keys: 2470efd51863SBarry Smith . -snes_grid_sequence <steps> 2471efd51863SBarry Smith 2472efd51863SBarry Smith Level: intermediate 2473efd51863SBarry Smith 2474c0df2a02SJed Brown Notes: 2475c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2476c0df2a02SJed Brown 2477efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2478efd51863SBarry Smith 2479efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2480efd51863SBarry Smith 2481efd51863SBarry Smith @*/ 2482efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2483efd51863SBarry Smith { 2484efd51863SBarry Smith PetscFunctionBegin; 2485efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2486efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2487efd51863SBarry Smith snes->gridsequence = steps; 2488efd51863SBarry Smith PetscFunctionReturn(0); 2489efd51863SBarry Smith } 2490efd51863SBarry Smith 2491efd51863SBarry Smith #undef __FUNCT__ 2492a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2493a8054027SBarry Smith /*@ 2494a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2495a8054027SBarry Smith 24963f9fe445SBarry Smith Not Collective 2497a8054027SBarry Smith 2498a8054027SBarry Smith Input Parameter: 2499a8054027SBarry Smith . snes - the SNES context 2500a8054027SBarry Smith 2501a8054027SBarry Smith Output Parameter: 2502a8054027SBarry 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 25033b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2504a8054027SBarry Smith 2505a8054027SBarry Smith Options Database Keys: 2506a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2507a8054027SBarry Smith 2508a8054027SBarry Smith Notes: 2509a8054027SBarry Smith The default is 1 2510a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2511a8054027SBarry Smith 2512a8054027SBarry Smith Level: intermediate 2513a8054027SBarry Smith 2514a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2515a8054027SBarry Smith 2516a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2517a8054027SBarry Smith 2518a8054027SBarry Smith @*/ 25197087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2520a8054027SBarry Smith { 2521a8054027SBarry Smith PetscFunctionBegin; 25220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2523a8054027SBarry Smith *lag = snes->lagpreconditioner; 2524a8054027SBarry Smith PetscFunctionReturn(0); 2525a8054027SBarry Smith } 2526a8054027SBarry Smith 2527a8054027SBarry Smith #undef __FUNCT__ 2528e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2529e35cf81dSBarry Smith /*@ 2530e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2531e35cf81dSBarry Smith often the preconditioner is rebuilt. 2532e35cf81dSBarry Smith 25333f9fe445SBarry Smith Logically Collective on SNES 2534e35cf81dSBarry Smith 2535e35cf81dSBarry Smith Input Parameters: 2536e35cf81dSBarry Smith + snes - the SNES context 2537e35cf81dSBarry 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 2538fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2539e35cf81dSBarry Smith 2540e35cf81dSBarry Smith Options Database Keys: 2541e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2542e35cf81dSBarry Smith 2543e35cf81dSBarry Smith Notes: 2544e35cf81dSBarry Smith The default is 1 2545e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2546fe3ffe1eSBarry 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 2547fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2548e35cf81dSBarry Smith 2549e35cf81dSBarry Smith Level: intermediate 2550e35cf81dSBarry Smith 2551e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2552e35cf81dSBarry Smith 2553e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2554e35cf81dSBarry Smith 2555e35cf81dSBarry Smith @*/ 25567087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2557e35cf81dSBarry Smith { 2558e35cf81dSBarry Smith PetscFunctionBegin; 25590700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2560e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2561e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2562c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2563e35cf81dSBarry Smith snes->lagjacobian = lag; 2564e35cf81dSBarry Smith PetscFunctionReturn(0); 2565e35cf81dSBarry Smith } 2566e35cf81dSBarry Smith 2567e35cf81dSBarry Smith #undef __FUNCT__ 2568e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2569e35cf81dSBarry Smith /*@ 2570e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2571e35cf81dSBarry Smith 25723f9fe445SBarry Smith Not Collective 2573e35cf81dSBarry Smith 2574e35cf81dSBarry Smith Input Parameter: 2575e35cf81dSBarry Smith . snes - the SNES context 2576e35cf81dSBarry Smith 2577e35cf81dSBarry Smith Output Parameter: 2578e35cf81dSBarry 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 2579e35cf81dSBarry Smith the Jacobian is built etc. 2580e35cf81dSBarry Smith 2581e35cf81dSBarry Smith Options Database Keys: 2582e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2583e35cf81dSBarry Smith 2584e35cf81dSBarry Smith Notes: 2585e35cf81dSBarry Smith The default is 1 2586e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2587e35cf81dSBarry Smith 2588e35cf81dSBarry Smith Level: intermediate 2589e35cf81dSBarry Smith 2590e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2591e35cf81dSBarry Smith 2592e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2593e35cf81dSBarry Smith 2594e35cf81dSBarry Smith @*/ 25957087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2596e35cf81dSBarry Smith { 2597e35cf81dSBarry Smith PetscFunctionBegin; 25980700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2599e35cf81dSBarry Smith *lag = snes->lagjacobian; 2600e35cf81dSBarry Smith PetscFunctionReturn(0); 2601e35cf81dSBarry Smith } 2602e35cf81dSBarry Smith 2603e35cf81dSBarry Smith #undef __FUNCT__ 26044a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 26059b94acceSBarry Smith /*@ 2606d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 26079b94acceSBarry Smith 26083f9fe445SBarry Smith Logically Collective on SNES 2609c7afd0dbSLois Curfman McInnes 26109b94acceSBarry Smith Input Parameters: 2611c7afd0dbSLois Curfman McInnes + snes - the SNES context 261270441072SBarry Smith . abstol - absolute convergence tolerance 261333174efeSLois Curfman McInnes . rtol - relative convergence tolerance 261433174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 261533174efeSLois Curfman McInnes of the change in the solution between steps 261633174efeSLois Curfman McInnes . maxit - maximum number of iterations 2617c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2618fee21e36SBarry Smith 261933174efeSLois Curfman McInnes Options Database Keys: 262070441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2621c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2622c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2623c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2624c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 26259b94acceSBarry Smith 2626d7a720efSLois Curfman McInnes Notes: 26279b94acceSBarry Smith The default maximum number of iterations is 50. 26289b94acceSBarry Smith The default maximum number of function evaluations is 1000. 26299b94acceSBarry Smith 263036851e7fSLois Curfman McInnes Level: intermediate 263136851e7fSLois Curfman McInnes 263233174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 26339b94acceSBarry Smith 26342492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 26359b94acceSBarry Smith @*/ 26367087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 26379b94acceSBarry Smith { 26383a40ed3dSBarry Smith PetscFunctionBegin; 26390700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2640c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2641c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2642c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2643c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2644c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2645c5eb9154SBarry Smith 2646ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2647ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2648ab54825eSJed Brown snes->abstol = abstol; 2649ab54825eSJed Brown } 2650ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2651ab54825eSJed 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); 2652ab54825eSJed Brown snes->rtol = rtol; 2653ab54825eSJed Brown } 2654ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2655ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2656c60f73f4SPeter Brune snes->stol = stol; 2657ab54825eSJed Brown } 2658ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2659ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2660ab54825eSJed Brown snes->max_its = maxit; 2661ab54825eSJed Brown } 2662ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2663ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2664ab54825eSJed Brown snes->max_funcs = maxf; 2665ab54825eSJed Brown } 266688976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 26673a40ed3dSBarry Smith PetscFunctionReturn(0); 26689b94acceSBarry Smith } 26699b94acceSBarry Smith 26704a2ae208SSatish Balay #undef __FUNCT__ 26714a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 26729b94acceSBarry Smith /*@ 267333174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 267433174efeSLois Curfman McInnes 2675c7afd0dbSLois Curfman McInnes Not Collective 2676c7afd0dbSLois Curfman McInnes 267733174efeSLois Curfman McInnes Input Parameters: 2678c7afd0dbSLois Curfman McInnes + snes - the SNES context 267985385478SLisandro Dalcin . atol - absolute convergence tolerance 268033174efeSLois Curfman McInnes . rtol - relative convergence tolerance 268133174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 268233174efeSLois Curfman McInnes of the change in the solution between steps 268333174efeSLois Curfman McInnes . maxit - maximum number of iterations 2684c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2685fee21e36SBarry Smith 268633174efeSLois Curfman McInnes Notes: 268733174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 268833174efeSLois Curfman McInnes 268936851e7fSLois Curfman McInnes Level: intermediate 269036851e7fSLois Curfman McInnes 269133174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 269233174efeSLois Curfman McInnes 269333174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 269433174efeSLois Curfman McInnes @*/ 26957087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 269633174efeSLois Curfman McInnes { 26973a40ed3dSBarry Smith PetscFunctionBegin; 26980700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 269985385478SLisandro Dalcin if (atol) *atol = snes->abstol; 270033174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 2701c60f73f4SPeter Brune if (stol) *stol = snes->stol; 270233174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 270333174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 27043a40ed3dSBarry Smith PetscFunctionReturn(0); 270533174efeSLois Curfman McInnes } 270633174efeSLois Curfman McInnes 27074a2ae208SSatish Balay #undef __FUNCT__ 27084a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 270933174efeSLois Curfman McInnes /*@ 27109b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 27119b94acceSBarry Smith 27123f9fe445SBarry Smith Logically Collective on SNES 2713fee21e36SBarry Smith 2714c7afd0dbSLois Curfman McInnes Input Parameters: 2715c7afd0dbSLois Curfman McInnes + snes - the SNES context 2716c7afd0dbSLois Curfman McInnes - tol - tolerance 2717c7afd0dbSLois Curfman McInnes 27189b94acceSBarry Smith Options Database Key: 2719c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 27209b94acceSBarry Smith 272136851e7fSLois Curfman McInnes Level: intermediate 272236851e7fSLois Curfman McInnes 27239b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 27249b94acceSBarry Smith 27252492ecdbSBarry Smith .seealso: SNESSetTolerances() 27269b94acceSBarry Smith @*/ 27277087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 27289b94acceSBarry Smith { 27293a40ed3dSBarry Smith PetscFunctionBegin; 27300700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2731c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 27329b94acceSBarry Smith snes->deltatol = tol; 27333a40ed3dSBarry Smith PetscFunctionReturn(0); 27349b94acceSBarry Smith } 27359b94acceSBarry Smith 2736df9fa365SBarry Smith /* 2737df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2738df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2739df9fa365SBarry Smith macros instead of functions 2740df9fa365SBarry Smith */ 27414a2ae208SSatish Balay #undef __FUNCT__ 2742a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 27437087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2744ce1608b8SBarry Smith { 2745dfbe8321SBarry Smith PetscErrorCode ierr; 2746ce1608b8SBarry Smith 2747ce1608b8SBarry Smith PetscFunctionBegin; 27480700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2749a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2750ce1608b8SBarry Smith PetscFunctionReturn(0); 2751ce1608b8SBarry Smith } 2752ce1608b8SBarry Smith 27534a2ae208SSatish Balay #undef __FUNCT__ 2754a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 27557087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2756df9fa365SBarry Smith { 2757dfbe8321SBarry Smith PetscErrorCode ierr; 2758df9fa365SBarry Smith 2759df9fa365SBarry Smith PetscFunctionBegin; 2760a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2761df9fa365SBarry Smith PetscFunctionReturn(0); 2762df9fa365SBarry Smith } 2763df9fa365SBarry Smith 27644a2ae208SSatish Balay #undef __FUNCT__ 2765a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 27666bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2767df9fa365SBarry Smith { 2768dfbe8321SBarry Smith PetscErrorCode ierr; 2769df9fa365SBarry Smith 2770df9fa365SBarry Smith PetscFunctionBegin; 2771a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2772df9fa365SBarry Smith PetscFunctionReturn(0); 2773df9fa365SBarry Smith } 2774df9fa365SBarry Smith 27757087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2776b271bb04SBarry Smith #undef __FUNCT__ 2777b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 27787087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2779b271bb04SBarry Smith { 2780b271bb04SBarry Smith PetscDrawLG lg; 2781b271bb04SBarry Smith PetscErrorCode ierr; 2782b271bb04SBarry Smith PetscReal x,y,per; 2783b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2784b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2785b271bb04SBarry Smith PetscDraw draw; 2786b271bb04SBarry Smith PetscFunctionBegin; 2787b271bb04SBarry Smith if (!monctx) { 2788b271bb04SBarry Smith MPI_Comm comm; 2789b271bb04SBarry Smith 2790b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2791b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2792b271bb04SBarry Smith } 2793b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2794b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2795b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2796b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2797b271bb04SBarry Smith x = (PetscReal) n; 2798b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2799b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2800b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2801b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2802b271bb04SBarry Smith } 2803b271bb04SBarry Smith 2804b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2805b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2806b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2807b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2808b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2809b271bb04SBarry Smith x = (PetscReal) n; 2810b271bb04SBarry Smith y = 100.0*per; 2811b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2812b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2813b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2814b271bb04SBarry Smith } 2815b271bb04SBarry Smith 2816b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2817b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2818b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2819b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2820b271bb04SBarry Smith x = (PetscReal) n; 2821b271bb04SBarry Smith y = (prev - rnorm)/prev; 2822b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2823b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2824b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2825b271bb04SBarry Smith } 2826b271bb04SBarry Smith 2827b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2828b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2829b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2830b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2831b271bb04SBarry Smith x = (PetscReal) n; 2832b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2833b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2834b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2835b271bb04SBarry Smith } 2836b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2837b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2838b271bb04SBarry Smith } 2839b271bb04SBarry Smith prev = rnorm; 2840b271bb04SBarry Smith PetscFunctionReturn(0); 2841b271bb04SBarry Smith } 2842b271bb04SBarry Smith 2843b271bb04SBarry Smith #undef __FUNCT__ 2844b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 28457087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2846b271bb04SBarry Smith { 2847b271bb04SBarry Smith PetscErrorCode ierr; 2848b271bb04SBarry Smith 2849b271bb04SBarry Smith PetscFunctionBegin; 2850b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2851b271bb04SBarry Smith PetscFunctionReturn(0); 2852b271bb04SBarry Smith } 2853b271bb04SBarry Smith 2854b271bb04SBarry Smith #undef __FUNCT__ 2855b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 28566bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2857b271bb04SBarry Smith { 2858b271bb04SBarry Smith PetscErrorCode ierr; 2859b271bb04SBarry Smith 2860b271bb04SBarry Smith PetscFunctionBegin; 2861b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2862b271bb04SBarry Smith PetscFunctionReturn(0); 2863b271bb04SBarry Smith } 2864b271bb04SBarry Smith 28657a03ce2fSLisandro Dalcin #undef __FUNCT__ 28667a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 2867228d79bcSJed Brown /*@ 2868228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 2869228d79bcSJed Brown 2870228d79bcSJed Brown Collective on SNES 2871228d79bcSJed Brown 2872228d79bcSJed Brown Input Parameters: 2873228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 2874228d79bcSJed Brown . iter - iteration number 2875228d79bcSJed Brown - rnorm - relative norm of the residual 2876228d79bcSJed Brown 2877228d79bcSJed Brown Notes: 2878228d79bcSJed Brown This routine is called by the SNES implementations. 2879228d79bcSJed Brown It does not typically need to be called by the user. 2880228d79bcSJed Brown 2881228d79bcSJed Brown Level: developer 2882228d79bcSJed Brown 2883228d79bcSJed Brown .seealso: SNESMonitorSet() 2884228d79bcSJed Brown @*/ 28857a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 28867a03ce2fSLisandro Dalcin { 28877a03ce2fSLisandro Dalcin PetscErrorCode ierr; 28887a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 28897a03ce2fSLisandro Dalcin 28907a03ce2fSLisandro Dalcin PetscFunctionBegin; 28917a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 28927a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 28937a03ce2fSLisandro Dalcin } 28947a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 28957a03ce2fSLisandro Dalcin } 28967a03ce2fSLisandro Dalcin 28979b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 28989b94acceSBarry Smith 28994a2ae208SSatish Balay #undef __FUNCT__ 2900a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 29019b94acceSBarry Smith /*@C 2902a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 29039b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 29049b94acceSBarry Smith progress. 29059b94acceSBarry Smith 29063f9fe445SBarry Smith Logically Collective on SNES 2907fee21e36SBarry Smith 2908c7afd0dbSLois Curfman McInnes Input Parameters: 2909c7afd0dbSLois Curfman McInnes + snes - the SNES context 2910c7afd0dbSLois Curfman McInnes . func - monitoring routine 2911b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 2912e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 2913b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 2914b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 29159b94acceSBarry Smith 2916c7afd0dbSLois Curfman McInnes Calling sequence of func: 2917a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2918c7afd0dbSLois Curfman McInnes 2919c7afd0dbSLois Curfman McInnes + snes - the SNES context 2920c7afd0dbSLois Curfman McInnes . its - iteration number 2921c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 292240a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 29239b94acceSBarry Smith 29249665c990SLois Curfman McInnes Options Database Keys: 2925a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 2926a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 2927a6570f20SBarry Smith uses SNESMonitorLGCreate() 2928cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 2929c7afd0dbSLois Curfman McInnes been hardwired into a code by 2930a6570f20SBarry Smith calls to SNESMonitorSet(), but 2931c7afd0dbSLois Curfman McInnes does not cancel those set via 2932c7afd0dbSLois Curfman McInnes the options database. 29339665c990SLois Curfman McInnes 2934639f9d9dSBarry Smith Notes: 29356bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 2936a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 29376bc08f3fSLois Curfman McInnes order in which they were set. 2938639f9d9dSBarry Smith 2939025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 2940025f1a04SBarry Smith 294136851e7fSLois Curfman McInnes Level: intermediate 294236851e7fSLois Curfman McInnes 29439b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 29449b94acceSBarry Smith 2945a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 29469b94acceSBarry Smith @*/ 2947c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 29489b94acceSBarry Smith { 2949b90d0a6eSBarry Smith PetscInt i; 2950649052a6SBarry Smith PetscErrorCode ierr; 2951b90d0a6eSBarry Smith 29523a40ed3dSBarry Smith PetscFunctionBegin; 29530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 295417186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2955b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 2956649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 2957649052a6SBarry Smith if (monitordestroy) { 2958c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 2959649052a6SBarry Smith } 2960b90d0a6eSBarry Smith PetscFunctionReturn(0); 2961b90d0a6eSBarry Smith } 2962b90d0a6eSBarry Smith } 2963b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 2964b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 2965639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 29663a40ed3dSBarry Smith PetscFunctionReturn(0); 29679b94acceSBarry Smith } 29689b94acceSBarry Smith 29694a2ae208SSatish Balay #undef __FUNCT__ 2970a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 29715cd90555SBarry Smith /*@C 2972a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 29735cd90555SBarry Smith 29743f9fe445SBarry Smith Logically Collective on SNES 2975c7afd0dbSLois Curfman McInnes 29765cd90555SBarry Smith Input Parameters: 29775cd90555SBarry Smith . snes - the SNES context 29785cd90555SBarry Smith 29791a480d89SAdministrator Options Database Key: 2980a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 2981a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 2982c7afd0dbSLois Curfman McInnes set via the options database 29835cd90555SBarry Smith 29845cd90555SBarry Smith Notes: 29855cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 29865cd90555SBarry Smith 298736851e7fSLois Curfman McInnes Level: intermediate 298836851e7fSLois Curfman McInnes 29895cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 29905cd90555SBarry Smith 2991a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 29925cd90555SBarry Smith @*/ 29937087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 29945cd90555SBarry Smith { 2995d952e501SBarry Smith PetscErrorCode ierr; 2996d952e501SBarry Smith PetscInt i; 2997d952e501SBarry Smith 29985cd90555SBarry Smith PetscFunctionBegin; 29990700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3000d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 3001d952e501SBarry Smith if (snes->monitordestroy[i]) { 30023c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 3003d952e501SBarry Smith } 3004d952e501SBarry Smith } 30055cd90555SBarry Smith snes->numbermonitors = 0; 30065cd90555SBarry Smith PetscFunctionReturn(0); 30075cd90555SBarry Smith } 30085cd90555SBarry Smith 30094a2ae208SSatish Balay #undef __FUNCT__ 30104a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 30119b94acceSBarry Smith /*@C 30129b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 30139b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 30149b94acceSBarry Smith 30153f9fe445SBarry Smith Logically Collective on SNES 3016fee21e36SBarry Smith 3017c7afd0dbSLois Curfman McInnes Input Parameters: 3018c7afd0dbSLois Curfman McInnes + snes - the SNES context 3019c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 30207f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 30217f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 30229b94acceSBarry Smith 3023c7afd0dbSLois Curfman McInnes Calling sequence of func: 302406ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 3025c7afd0dbSLois Curfman McInnes 3026c7afd0dbSLois Curfman McInnes + snes - the SNES context 302706ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 3028c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 3029184914b5SBarry Smith . reason - reason for convergence/divergence 3030c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 30314b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 30324b27c08aSLois Curfman McInnes - f - 2-norm of function 30339b94acceSBarry Smith 303436851e7fSLois Curfman McInnes Level: advanced 303536851e7fSLois Curfman McInnes 30369b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 30379b94acceSBarry Smith 303885385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 30399b94acceSBarry Smith @*/ 30407087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 30419b94acceSBarry Smith { 30427f7931b9SBarry Smith PetscErrorCode ierr; 30437f7931b9SBarry Smith 30443a40ed3dSBarry Smith PetscFunctionBegin; 30450700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 304685385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 30477f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 30487f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 30497f7931b9SBarry Smith } 305085385478SLisandro Dalcin snes->ops->converged = func; 30517f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 305285385478SLisandro Dalcin snes->cnvP = cctx; 30533a40ed3dSBarry Smith PetscFunctionReturn(0); 30549b94acceSBarry Smith } 30559b94acceSBarry Smith 30564a2ae208SSatish Balay #undef __FUNCT__ 30574a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 305852baeb72SSatish Balay /*@ 3059184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 3060184914b5SBarry Smith 3061184914b5SBarry Smith Not Collective 3062184914b5SBarry Smith 3063184914b5SBarry Smith Input Parameter: 3064184914b5SBarry Smith . snes - the SNES context 3065184914b5SBarry Smith 3066184914b5SBarry Smith Output Parameter: 30674d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 3068184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 3069184914b5SBarry Smith 3070184914b5SBarry Smith Level: intermediate 3071184914b5SBarry Smith 3072184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 3073184914b5SBarry Smith 3074184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 3075184914b5SBarry Smith 307685385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 3077184914b5SBarry Smith @*/ 30787087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 3079184914b5SBarry Smith { 3080184914b5SBarry Smith PetscFunctionBegin; 30810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 30824482741eSBarry Smith PetscValidPointer(reason,2); 3083184914b5SBarry Smith *reason = snes->reason; 3084184914b5SBarry Smith PetscFunctionReturn(0); 3085184914b5SBarry Smith } 3086184914b5SBarry Smith 30874a2ae208SSatish Balay #undef __FUNCT__ 30884a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 3089c9005455SLois Curfman McInnes /*@ 3090c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 3091c9005455SLois Curfman McInnes 30923f9fe445SBarry Smith Logically Collective on SNES 3093fee21e36SBarry Smith 3094c7afd0dbSLois Curfman McInnes Input Parameters: 3095c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 30968c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 3097cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 3098758f92a0SBarry Smith . na - size of a and its 309964731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 3100758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 3101c7afd0dbSLois Curfman McInnes 3102308dcc3eSBarry Smith Notes: 3103308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 3104308dcc3eSBarry Smith default array of length 10000 is allocated. 3105308dcc3eSBarry Smith 3106c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 3107c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 3108c9005455SLois Curfman McInnes during the section of code that is being timed. 3109c9005455SLois Curfman McInnes 311036851e7fSLois Curfman McInnes Level: intermediate 311136851e7fSLois Curfman McInnes 3112c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 3113758f92a0SBarry Smith 311408405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 3115758f92a0SBarry Smith 3116c9005455SLois Curfman McInnes @*/ 31177087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 3118c9005455SLois Curfman McInnes { 3119308dcc3eSBarry Smith PetscErrorCode ierr; 3120308dcc3eSBarry Smith 31213a40ed3dSBarry Smith PetscFunctionBegin; 31220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31234482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 3124a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 3125308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 3126308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 3127308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 3128308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 3129308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 3130308dcc3eSBarry Smith } 3131c9005455SLois Curfman McInnes snes->conv_hist = a; 3132758f92a0SBarry Smith snes->conv_hist_its = its; 3133758f92a0SBarry Smith snes->conv_hist_max = na; 3134a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 3135758f92a0SBarry Smith snes->conv_hist_reset = reset; 3136758f92a0SBarry Smith PetscFunctionReturn(0); 3137758f92a0SBarry Smith } 3138758f92a0SBarry Smith 3139308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3140c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 3141c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 3142308dcc3eSBarry Smith EXTERN_C_BEGIN 3143308dcc3eSBarry Smith #undef __FUNCT__ 3144308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 3145308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3146308dcc3eSBarry Smith { 3147308dcc3eSBarry Smith mxArray *mat; 3148308dcc3eSBarry Smith PetscInt i; 3149308dcc3eSBarry Smith PetscReal *ar; 3150308dcc3eSBarry Smith 3151308dcc3eSBarry Smith PetscFunctionBegin; 3152308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3153308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3154308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 3155308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 3156308dcc3eSBarry Smith } 3157308dcc3eSBarry Smith PetscFunctionReturn(mat); 3158308dcc3eSBarry Smith } 3159308dcc3eSBarry Smith EXTERN_C_END 3160308dcc3eSBarry Smith #endif 3161308dcc3eSBarry Smith 3162308dcc3eSBarry Smith 31634a2ae208SSatish Balay #undef __FUNCT__ 31644a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 31650c4c9dddSBarry Smith /*@C 3166758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3167758f92a0SBarry Smith 31683f9fe445SBarry Smith Not Collective 3169758f92a0SBarry Smith 3170758f92a0SBarry Smith Input Parameter: 3171758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3172758f92a0SBarry Smith 3173758f92a0SBarry Smith Output Parameters: 3174758f92a0SBarry Smith . a - array to hold history 3175758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3176758f92a0SBarry Smith negative if not converged) for each solve. 3177758f92a0SBarry Smith - na - size of a and its 3178758f92a0SBarry Smith 3179758f92a0SBarry Smith Notes: 3180758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3181758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3182758f92a0SBarry Smith 3183758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3184758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3185758f92a0SBarry Smith during the section of code that is being timed. 3186758f92a0SBarry Smith 3187758f92a0SBarry Smith Level: intermediate 3188758f92a0SBarry Smith 3189758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3190758f92a0SBarry Smith 3191758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3192758f92a0SBarry Smith 3193758f92a0SBarry Smith @*/ 31947087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3195758f92a0SBarry Smith { 3196758f92a0SBarry Smith PetscFunctionBegin; 31970700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3198758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3199758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3200758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 32013a40ed3dSBarry Smith PetscFunctionReturn(0); 3202c9005455SLois Curfman McInnes } 3203c9005455SLois Curfman McInnes 3204e74ef692SMatthew Knepley #undef __FUNCT__ 3205e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 3206ac226902SBarry Smith /*@C 320776b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3208eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 32097e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 321076b2cf59SMatthew Knepley 32113f9fe445SBarry Smith Logically Collective on SNES 321276b2cf59SMatthew Knepley 321376b2cf59SMatthew Knepley Input Parameters: 321476b2cf59SMatthew Knepley . snes - The nonlinear solver context 321576b2cf59SMatthew Knepley . func - The function 321676b2cf59SMatthew Knepley 321776b2cf59SMatthew Knepley Calling sequence of func: 3218b5d30489SBarry Smith . func (SNES snes, PetscInt step); 321976b2cf59SMatthew Knepley 322076b2cf59SMatthew Knepley . step - The current step of the iteration 322176b2cf59SMatthew Knepley 3222fe97e370SBarry Smith Level: advanced 3223fe97e370SBarry Smith 3224fe97e370SBarry 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() 3225fe97e370SBarry Smith This is not used by most users. 322676b2cf59SMatthew Knepley 322776b2cf59SMatthew Knepley .keywords: SNES, update 3228b5d30489SBarry Smith 322985385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 323076b2cf59SMatthew Knepley @*/ 32317087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 323276b2cf59SMatthew Knepley { 323376b2cf59SMatthew Knepley PetscFunctionBegin; 32340700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3235e7788613SBarry Smith snes->ops->update = func; 323676b2cf59SMatthew Knepley PetscFunctionReturn(0); 323776b2cf59SMatthew Knepley } 323876b2cf59SMatthew Knepley 3239e74ef692SMatthew Knepley #undef __FUNCT__ 3240e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 324176b2cf59SMatthew Knepley /*@ 324276b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 324376b2cf59SMatthew Knepley 324476b2cf59SMatthew Knepley Not collective 324576b2cf59SMatthew Knepley 324676b2cf59SMatthew Knepley Input Parameters: 324776b2cf59SMatthew Knepley . snes - The nonlinear solver context 324876b2cf59SMatthew Knepley . step - The current step of the iteration 324976b2cf59SMatthew Knepley 3250205452f4SMatthew Knepley Level: intermediate 3251205452f4SMatthew Knepley 325276b2cf59SMatthew Knepley .keywords: SNES, update 3253a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 325476b2cf59SMatthew Knepley @*/ 32557087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 325676b2cf59SMatthew Knepley { 325776b2cf59SMatthew Knepley PetscFunctionBegin; 325876b2cf59SMatthew Knepley PetscFunctionReturn(0); 325976b2cf59SMatthew Knepley } 326076b2cf59SMatthew Knepley 32614a2ae208SSatish Balay #undef __FUNCT__ 32624a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 32639b94acceSBarry Smith /* 32649b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 32659b94acceSBarry Smith positive parameter delta. 32669b94acceSBarry Smith 32679b94acceSBarry Smith Input Parameters: 3268c7afd0dbSLois Curfman McInnes + snes - the SNES context 32699b94acceSBarry Smith . y - approximate solution of linear system 32709b94acceSBarry Smith . fnorm - 2-norm of current function 3271c7afd0dbSLois Curfman McInnes - delta - trust region size 32729b94acceSBarry Smith 32739b94acceSBarry Smith Output Parameters: 3274c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 32759b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 32769b94acceSBarry Smith region, and exceeds zero otherwise. 3277c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 32789b94acceSBarry Smith 32799b94acceSBarry Smith Note: 32804b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 32819b94acceSBarry Smith is set to be the maximum allowable step size. 32829b94acceSBarry Smith 32839b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 32849b94acceSBarry Smith */ 3285dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 32869b94acceSBarry Smith { 3287064f8208SBarry Smith PetscReal nrm; 3288ea709b57SSatish Balay PetscScalar cnorm; 3289dfbe8321SBarry Smith PetscErrorCode ierr; 32903a40ed3dSBarry Smith 32913a40ed3dSBarry Smith PetscFunctionBegin; 32920700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 32930700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3294c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3295184914b5SBarry Smith 3296064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3297064f8208SBarry Smith if (nrm > *delta) { 3298064f8208SBarry Smith nrm = *delta/nrm; 3299064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3300064f8208SBarry Smith cnorm = nrm; 33012dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 33029b94acceSBarry Smith *ynorm = *delta; 33039b94acceSBarry Smith } else { 33049b94acceSBarry Smith *gpnorm = 0.0; 3305064f8208SBarry Smith *ynorm = nrm; 33069b94acceSBarry Smith } 33073a40ed3dSBarry Smith PetscFunctionReturn(0); 33089b94acceSBarry Smith } 33099b94acceSBarry Smith 33104a2ae208SSatish Balay #undef __FUNCT__ 33114a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 33126ce558aeSBarry Smith /*@C 3313f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3314f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 33159b94acceSBarry Smith 3316c7afd0dbSLois Curfman McInnes Collective on SNES 3317c7afd0dbSLois Curfman McInnes 3318b2002411SLois Curfman McInnes Input Parameters: 3319c7afd0dbSLois Curfman McInnes + snes - the SNES context 33203cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 332185385478SLisandro Dalcin - x - the solution vector. 33229b94acceSBarry Smith 3323b2002411SLois Curfman McInnes Notes: 33248ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 33258ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 33268ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 33278ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 33288ddd3da0SLois Curfman McInnes 332936851e7fSLois Curfman McInnes Level: beginner 333036851e7fSLois Curfman McInnes 33319b94acceSBarry Smith .keywords: SNES, nonlinear, solve 33329b94acceSBarry Smith 3333c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 33349b94acceSBarry Smith @*/ 33357087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 33369b94acceSBarry Smith { 3337dfbe8321SBarry Smith PetscErrorCode ierr; 3338ace3abfcSBarry Smith PetscBool flg; 3339eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 3340eabae89aSBarry Smith PetscViewer viewer; 3341efd51863SBarry Smith PetscInt grid; 3342a69afd8bSBarry Smith Vec xcreated = PETSC_NULL; 3343caa4e7f2SJed Brown DM dm; 3344052efed2SBarry Smith 33453a40ed3dSBarry Smith PetscFunctionBegin; 33460700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3347a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3348a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 33490700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 335085385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 335185385478SLisandro Dalcin 3352caa4e7f2SJed Brown if (!x) { 3353caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3354caa4e7f2SJed Brown ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 3355a69afd8bSBarry Smith x = xcreated; 3356a69afd8bSBarry Smith } 3357a69afd8bSBarry Smith 3358a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3359efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3360efd51863SBarry Smith 336185385478SLisandro Dalcin /* set solution vector */ 3362efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 33636bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 336485385478SLisandro Dalcin snes->vec_sol = x; 3365caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3366caa4e7f2SJed Brown 3367caa4e7f2SJed Brown /* set affine vector if provided */ 336885385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 33696bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 337085385478SLisandro Dalcin snes->vec_rhs = b; 337185385478SLisandro Dalcin 337270e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 33733f149594SLisandro Dalcin 33747eee914bSBarry Smith if (!grid) { 33757eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3376d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3377dd568438SSatish Balay } else if (snes->dm) { 3378dd568438SSatish Balay PetscBool ig; 3379dd568438SSatish Balay ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr); 3380dd568438SSatish Balay if (ig) { 33817eee914bSBarry Smith ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr); 33827eee914bSBarry Smith } 3383d25893d9SBarry Smith } 3384dd568438SSatish Balay } 3385d25893d9SBarry Smith 3386abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 338750ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3388d5e45103SBarry Smith 33893f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 33904936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 339185385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 33924936397dSBarry Smith if (snes->domainerror){ 33934936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 33944936397dSBarry Smith snes->domainerror = PETSC_FALSE; 33954936397dSBarry Smith } 339617186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 33973f149594SLisandro Dalcin 33987adad957SLisandro Dalcin ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 3399eabae89aSBarry Smith if (flg && !PetscPreLoadingOn) { 34007adad957SLisandro Dalcin ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 3401eabae89aSBarry Smith ierr = SNESView(snes,viewer);CHKERRQ(ierr); 34026bf464f9SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3403eabae89aSBarry Smith } 3404eabae89aSBarry Smith 340590d69ab7SBarry Smith flg = PETSC_FALSE; 3406acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3407da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 34085968eb51SBarry Smith if (snes->printreason) { 3409a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 34105968eb51SBarry Smith if (snes->reason > 0) { 3411c7e7b494SJed 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); 34125968eb51SBarry Smith } else { 3413c7e7b494SJed 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); 34145968eb51SBarry Smith } 3415a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 34165968eb51SBarry Smith } 34175968eb51SBarry Smith 34188501fc72SJed Brown flg = PETSC_FALSE; 34198501fc72SJed Brown ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 34208501fc72SJed Brown if (flg) { 34218501fc72SJed Brown PetscViewer viewer; 34228501fc72SJed Brown ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 34238501fc72SJed Brown ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 34248501fc72SJed Brown ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 34258501fc72SJed Brown ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 34268501fc72SJed Brown ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 34278501fc72SJed Brown } 34288501fc72SJed Brown 3429e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3430efd51863SBarry Smith if (grid < snes->gridsequence) { 3431efd51863SBarry Smith DM fine; 3432efd51863SBarry Smith Vec xnew; 3433efd51863SBarry Smith Mat interp; 3434efd51863SBarry Smith 3435efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3436c5c77316SJed Brown if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 3437e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3438efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3439efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3440efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3441efd51863SBarry Smith x = xnew; 3442efd51863SBarry Smith 3443efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3444efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3445efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3446a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3447efd51863SBarry Smith } 3448efd51863SBarry Smith } 3449a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 34503a40ed3dSBarry Smith PetscFunctionReturn(0); 34519b94acceSBarry Smith } 34529b94acceSBarry Smith 34539b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 34549b94acceSBarry Smith 34554a2ae208SSatish Balay #undef __FUNCT__ 34564a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 345782bf6240SBarry Smith /*@C 34584b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 34599b94acceSBarry Smith 3460fee21e36SBarry Smith Collective on SNES 3461fee21e36SBarry Smith 3462c7afd0dbSLois Curfman McInnes Input Parameters: 3463c7afd0dbSLois Curfman McInnes + snes - the SNES context 3464454a90a3SBarry Smith - type - a known method 3465c7afd0dbSLois Curfman McInnes 3466c7afd0dbSLois Curfman McInnes Options Database Key: 3467454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3468c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3469ae12b187SLois Curfman McInnes 34709b94acceSBarry Smith Notes: 3471e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 34724b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3473c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 34744b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3475c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 34769b94acceSBarry Smith 3477ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3478ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3479ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3480ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3481ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3482ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3483ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3484ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3485ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3486b0a32e0cSBarry Smith appropriate method. 348736851e7fSLois Curfman McInnes 348836851e7fSLois Curfman McInnes Level: intermediate 3489a703fe33SLois Curfman McInnes 3490454a90a3SBarry Smith .keywords: SNES, set, type 3491435da068SBarry Smith 3492435da068SBarry Smith .seealso: SNESType, SNESCreate() 3493435da068SBarry Smith 34949b94acceSBarry Smith @*/ 34957087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 34969b94acceSBarry Smith { 3497dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3498ace3abfcSBarry Smith PetscBool match; 34993a40ed3dSBarry Smith 35003a40ed3dSBarry Smith PetscFunctionBegin; 35010700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35024482741eSBarry Smith PetscValidCharPointer(type,2); 350382bf6240SBarry Smith 35046831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 35050f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 350692ff6ae8SBarry Smith 35074b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3508e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 350975396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 3510b5c23020SJed Brown if (snes->ops->destroy) { 3511b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 3512b5c23020SJed Brown snes->ops->destroy = PETSC_NULL; 3513b5c23020SJed Brown } 351475396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 351575396ef9SLisandro Dalcin snes->ops->setup = 0; 351675396ef9SLisandro Dalcin snes->ops->solve = 0; 351775396ef9SLisandro Dalcin snes->ops->view = 0; 351875396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 351975396ef9SLisandro Dalcin snes->ops->destroy = 0; 352075396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 352175396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3522454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 352303bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 35249fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 35259fb22e1aSBarry Smith if (PetscAMSPublishAll) { 35269fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 35279fb22e1aSBarry Smith } 35289fb22e1aSBarry Smith #endif 35293a40ed3dSBarry Smith PetscFunctionReturn(0); 35309b94acceSBarry Smith } 35319b94acceSBarry Smith 3532a847f771SSatish Balay 35339b94acceSBarry Smith /* --------------------------------------------------------------------- */ 35344a2ae208SSatish Balay #undef __FUNCT__ 35354a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 353652baeb72SSatish Balay /*@ 35379b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3538f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 35399b94acceSBarry Smith 3540fee21e36SBarry Smith Not Collective 3541fee21e36SBarry Smith 354236851e7fSLois Curfman McInnes Level: advanced 354336851e7fSLois Curfman McInnes 35449b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 35459b94acceSBarry Smith 35469b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 35479b94acceSBarry Smith @*/ 35487087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 35499b94acceSBarry Smith { 3550dfbe8321SBarry Smith PetscErrorCode ierr; 355182bf6240SBarry Smith 35523a40ed3dSBarry Smith PetscFunctionBegin; 35531441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 35544c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 35553a40ed3dSBarry Smith PetscFunctionReturn(0); 35569b94acceSBarry Smith } 35579b94acceSBarry Smith 35584a2ae208SSatish Balay #undef __FUNCT__ 35594a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 35609b94acceSBarry Smith /*@C 35619a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 35629b94acceSBarry Smith 3563c7afd0dbSLois Curfman McInnes Not Collective 3564c7afd0dbSLois Curfman McInnes 35659b94acceSBarry Smith Input Parameter: 35664b0e389bSBarry Smith . snes - nonlinear solver context 35679b94acceSBarry Smith 35689b94acceSBarry Smith Output Parameter: 35693a7fca6bSBarry Smith . type - SNES method (a character string) 35709b94acceSBarry Smith 357136851e7fSLois Curfman McInnes Level: intermediate 357236851e7fSLois Curfman McInnes 3573454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 35749b94acceSBarry Smith @*/ 35757087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 35769b94acceSBarry Smith { 35773a40ed3dSBarry Smith PetscFunctionBegin; 35780700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35794482741eSBarry Smith PetscValidPointer(type,2); 35807adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 35813a40ed3dSBarry Smith PetscFunctionReturn(0); 35829b94acceSBarry Smith } 35839b94acceSBarry Smith 35844a2ae208SSatish Balay #undef __FUNCT__ 35854a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 358652baeb72SSatish Balay /*@ 35879b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3588c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 35899b94acceSBarry Smith 3590c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3591c7afd0dbSLois Curfman McInnes 35929b94acceSBarry Smith Input Parameter: 35939b94acceSBarry Smith . snes - the SNES context 35949b94acceSBarry Smith 35959b94acceSBarry Smith Output Parameter: 35969b94acceSBarry Smith . x - the solution 35979b94acceSBarry Smith 359870e92668SMatthew Knepley Level: intermediate 359936851e7fSLois Curfman McInnes 36009b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 36019b94acceSBarry Smith 360285385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 36039b94acceSBarry Smith @*/ 36047087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 36059b94acceSBarry Smith { 36063a40ed3dSBarry Smith PetscFunctionBegin; 36070700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36084482741eSBarry Smith PetscValidPointer(x,2); 360985385478SLisandro Dalcin *x = snes->vec_sol; 361070e92668SMatthew Knepley PetscFunctionReturn(0); 361170e92668SMatthew Knepley } 361270e92668SMatthew Knepley 361370e92668SMatthew Knepley #undef __FUNCT__ 36144a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 361552baeb72SSatish Balay /*@ 36169b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 36179b94acceSBarry Smith stored. 36189b94acceSBarry Smith 3619c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3620c7afd0dbSLois Curfman McInnes 36219b94acceSBarry Smith Input Parameter: 36229b94acceSBarry Smith . snes - the SNES context 36239b94acceSBarry Smith 36249b94acceSBarry Smith Output Parameter: 36259b94acceSBarry Smith . x - the solution update 36269b94acceSBarry Smith 362736851e7fSLois Curfman McInnes Level: advanced 362836851e7fSLois Curfman McInnes 36299b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 36309b94acceSBarry Smith 363185385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 36329b94acceSBarry Smith @*/ 36337087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 36349b94acceSBarry Smith { 36353a40ed3dSBarry Smith PetscFunctionBegin; 36360700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36374482741eSBarry Smith PetscValidPointer(x,2); 363885385478SLisandro Dalcin *x = snes->vec_sol_update; 36393a40ed3dSBarry Smith PetscFunctionReturn(0); 36409b94acceSBarry Smith } 36419b94acceSBarry Smith 36424a2ae208SSatish Balay #undef __FUNCT__ 36434a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 36449b94acceSBarry Smith /*@C 36453638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 36469b94acceSBarry Smith 3647a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 3648c7afd0dbSLois Curfman McInnes 36499b94acceSBarry Smith Input Parameter: 36509b94acceSBarry Smith . snes - the SNES context 36519b94acceSBarry Smith 36529b94acceSBarry Smith Output Parameter: 36537bf4e008SBarry Smith + r - the function (or PETSC_NULL) 365470e92668SMatthew Knepley . func - the function (or PETSC_NULL) 365570e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 36569b94acceSBarry Smith 365736851e7fSLois Curfman McInnes Level: advanced 365836851e7fSLois Curfman McInnes 3659a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 36609b94acceSBarry Smith 36614b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 36629b94acceSBarry Smith @*/ 36637087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 36649b94acceSBarry Smith { 3665a63bb30eSJed Brown PetscErrorCode ierr; 36666cab3a1bSJed Brown DM dm; 3667a63bb30eSJed Brown 36683a40ed3dSBarry Smith PetscFunctionBegin; 36690700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3670a63bb30eSJed Brown if (r) { 3671a63bb30eSJed Brown if (!snes->vec_func) { 3672a63bb30eSJed Brown if (snes->vec_rhs) { 3673a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 3674a63bb30eSJed Brown } else if (snes->vec_sol) { 3675a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 3676a63bb30eSJed Brown } else if (snes->dm) { 3677a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 3678a63bb30eSJed Brown } 3679a63bb30eSJed Brown } 3680a63bb30eSJed Brown *r = snes->vec_func; 3681a63bb30eSJed Brown } 36826cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 36836cab3a1bSJed Brown ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr); 36843a40ed3dSBarry Smith PetscFunctionReturn(0); 36859b94acceSBarry Smith } 36869b94acceSBarry Smith 3687c79ef259SPeter Brune /*@C 3688c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3689c79ef259SPeter Brune 3690c79ef259SPeter Brune Input Parameter: 3691c79ef259SPeter Brune . snes - the SNES context 3692c79ef259SPeter Brune 3693c79ef259SPeter Brune Output Parameter: 3694c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3695c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3696c79ef259SPeter Brune 3697c79ef259SPeter Brune Level: advanced 3698c79ef259SPeter Brune 3699c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3700c79ef259SPeter Brune 3701c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3702c79ef259SPeter Brune @*/ 3703c79ef259SPeter Brune 37044a2ae208SSatish Balay #undef __FUNCT__ 3705646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3706646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3707646217ecSPeter Brune { 37086cab3a1bSJed Brown PetscErrorCode ierr; 37096cab3a1bSJed Brown DM dm; 37106cab3a1bSJed Brown 3711646217ecSPeter Brune PetscFunctionBegin; 3712646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37136cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 37146cab3a1bSJed Brown ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr); 3715646217ecSPeter Brune PetscFunctionReturn(0); 3716646217ecSPeter Brune } 3717646217ecSPeter Brune 37184a2ae208SSatish Balay #undef __FUNCT__ 37194a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 37203c7409f5SSatish Balay /*@C 37213c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3722d850072dSLois Curfman McInnes SNES options in the database. 37233c7409f5SSatish Balay 37243f9fe445SBarry Smith Logically Collective on SNES 3725fee21e36SBarry Smith 3726c7afd0dbSLois Curfman McInnes Input Parameter: 3727c7afd0dbSLois Curfman McInnes + snes - the SNES context 3728c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3729c7afd0dbSLois Curfman McInnes 3730d850072dSLois Curfman McInnes Notes: 3731a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3732c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3733d850072dSLois Curfman McInnes 373436851e7fSLois Curfman McInnes Level: advanced 373536851e7fSLois Curfman McInnes 37363c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3737a86d99e1SLois Curfman McInnes 3738a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 37393c7409f5SSatish Balay @*/ 37407087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 37413c7409f5SSatish Balay { 3742dfbe8321SBarry Smith PetscErrorCode ierr; 37433c7409f5SSatish Balay 37443a40ed3dSBarry Smith PetscFunctionBegin; 37450700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3746639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 37471cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 374894b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 37493a40ed3dSBarry Smith PetscFunctionReturn(0); 37503c7409f5SSatish Balay } 37513c7409f5SSatish Balay 37524a2ae208SSatish Balay #undef __FUNCT__ 37534a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 37543c7409f5SSatish Balay /*@C 3755f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3756d850072dSLois Curfman McInnes SNES options in the database. 37573c7409f5SSatish Balay 37583f9fe445SBarry Smith Logically Collective on SNES 3759fee21e36SBarry Smith 3760c7afd0dbSLois Curfman McInnes Input Parameters: 3761c7afd0dbSLois Curfman McInnes + snes - the SNES context 3762c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3763c7afd0dbSLois Curfman McInnes 3764d850072dSLois Curfman McInnes Notes: 3765a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3766c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3767d850072dSLois Curfman McInnes 376836851e7fSLois Curfman McInnes Level: advanced 376936851e7fSLois Curfman McInnes 37703c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3771a86d99e1SLois Curfman McInnes 3772a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 37733c7409f5SSatish Balay @*/ 37747087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 37753c7409f5SSatish Balay { 3776dfbe8321SBarry Smith PetscErrorCode ierr; 37773c7409f5SSatish Balay 37783a40ed3dSBarry Smith PetscFunctionBegin; 37790700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3780639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 37811cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 378294b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 37833a40ed3dSBarry Smith PetscFunctionReturn(0); 37843c7409f5SSatish Balay } 37853c7409f5SSatish Balay 37864a2ae208SSatish Balay #undef __FUNCT__ 37874a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 37889ab63eb5SSatish Balay /*@C 37893c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 37903c7409f5SSatish Balay SNES options in the database. 37913c7409f5SSatish Balay 3792c7afd0dbSLois Curfman McInnes Not Collective 3793c7afd0dbSLois Curfman McInnes 37943c7409f5SSatish Balay Input Parameter: 37953c7409f5SSatish Balay . snes - the SNES context 37963c7409f5SSatish Balay 37973c7409f5SSatish Balay Output Parameter: 37983c7409f5SSatish Balay . prefix - pointer to the prefix string used 37993c7409f5SSatish Balay 38004ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 38019ab63eb5SSatish Balay sufficient length to hold the prefix. 38029ab63eb5SSatish Balay 380336851e7fSLois Curfman McInnes Level: advanced 380436851e7fSLois Curfman McInnes 38053c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 3806a86d99e1SLois Curfman McInnes 3807a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 38083c7409f5SSatish Balay @*/ 38097087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 38103c7409f5SSatish Balay { 3811dfbe8321SBarry Smith PetscErrorCode ierr; 38123c7409f5SSatish Balay 38133a40ed3dSBarry Smith PetscFunctionBegin; 38140700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3815639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 38163a40ed3dSBarry Smith PetscFunctionReturn(0); 38173c7409f5SSatish Balay } 38183c7409f5SSatish Balay 3819b2002411SLois Curfman McInnes 38204a2ae208SSatish Balay #undef __FUNCT__ 38214a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 38223cea93caSBarry Smith /*@C 38233cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 38243cea93caSBarry Smith 38257f6c08e0SMatthew Knepley Level: advanced 38263cea93caSBarry Smith @*/ 38277087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3828b2002411SLois Curfman McInnes { 3829e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3830dfbe8321SBarry Smith PetscErrorCode ierr; 3831b2002411SLois Curfman McInnes 3832b2002411SLois Curfman McInnes PetscFunctionBegin; 3833b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3834c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3835b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3836b2002411SLois Curfman McInnes } 3837da9b6338SBarry Smith 3838da9b6338SBarry Smith #undef __FUNCT__ 3839da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 38407087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3841da9b6338SBarry Smith { 3842dfbe8321SBarry Smith PetscErrorCode ierr; 384377431f27SBarry Smith PetscInt N,i,j; 3844da9b6338SBarry Smith Vec u,uh,fh; 3845da9b6338SBarry Smith PetscScalar value; 3846da9b6338SBarry Smith PetscReal norm; 3847da9b6338SBarry Smith 3848da9b6338SBarry Smith PetscFunctionBegin; 3849da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3850da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3851da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3852da9b6338SBarry Smith 3853da9b6338SBarry Smith /* currently only works for sequential */ 3854da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3855da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3856da9b6338SBarry Smith for (i=0; i<N; i++) { 3857da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 385877431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3859da9b6338SBarry Smith for (j=-10; j<11; j++) { 3860ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3861da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 38623ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3863da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 386477431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3865da9b6338SBarry Smith value = -value; 3866da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3867da9b6338SBarry Smith } 3868da9b6338SBarry Smith } 38696bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 38706bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 3871da9b6338SBarry Smith PetscFunctionReturn(0); 3872da9b6338SBarry Smith } 387371f87433Sdalcinl 387471f87433Sdalcinl #undef __FUNCT__ 3875fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 387671f87433Sdalcinl /*@ 3877fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 387871f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 387971f87433Sdalcinl Newton method. 388071f87433Sdalcinl 38813f9fe445SBarry Smith Logically Collective on SNES 388271f87433Sdalcinl 388371f87433Sdalcinl Input Parameters: 388471f87433Sdalcinl + snes - SNES context 388571f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 388671f87433Sdalcinl 388764ba62caSBarry Smith Options Database: 388864ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 388964ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 389064ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 389164ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 389264ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 389364ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 389464ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 389564ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 389664ba62caSBarry Smith 389771f87433Sdalcinl Notes: 389871f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 389971f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 390071f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 390171f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 390271f87433Sdalcinl solver. 390371f87433Sdalcinl 390471f87433Sdalcinl Level: advanced 390571f87433Sdalcinl 390671f87433Sdalcinl Reference: 390771f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 390871f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 390971f87433Sdalcinl 391071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 391171f87433Sdalcinl 3912fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 391371f87433Sdalcinl @*/ 39147087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 391571f87433Sdalcinl { 391671f87433Sdalcinl PetscFunctionBegin; 39170700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3918acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 391971f87433Sdalcinl snes->ksp_ewconv = flag; 392071f87433Sdalcinl PetscFunctionReturn(0); 392171f87433Sdalcinl } 392271f87433Sdalcinl 392371f87433Sdalcinl #undef __FUNCT__ 3924fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 392571f87433Sdalcinl /*@ 3926fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 392771f87433Sdalcinl for computing relative tolerance for linear solvers within an 392871f87433Sdalcinl inexact Newton method. 392971f87433Sdalcinl 393071f87433Sdalcinl Not Collective 393171f87433Sdalcinl 393271f87433Sdalcinl Input Parameter: 393371f87433Sdalcinl . snes - SNES context 393471f87433Sdalcinl 393571f87433Sdalcinl Output Parameter: 393671f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 393771f87433Sdalcinl 393871f87433Sdalcinl Notes: 393971f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 394071f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 394171f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 394271f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 394371f87433Sdalcinl solver. 394471f87433Sdalcinl 394571f87433Sdalcinl Level: advanced 394671f87433Sdalcinl 394771f87433Sdalcinl Reference: 394871f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 394971f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 395071f87433Sdalcinl 395171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 395271f87433Sdalcinl 3953fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 395471f87433Sdalcinl @*/ 39557087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 395671f87433Sdalcinl { 395771f87433Sdalcinl PetscFunctionBegin; 39580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 395971f87433Sdalcinl PetscValidPointer(flag,2); 396071f87433Sdalcinl *flag = snes->ksp_ewconv; 396171f87433Sdalcinl PetscFunctionReturn(0); 396271f87433Sdalcinl } 396371f87433Sdalcinl 396471f87433Sdalcinl #undef __FUNCT__ 3965fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 396671f87433Sdalcinl /*@ 3967fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 396871f87433Sdalcinl convergence criteria for the linear solvers within an inexact 396971f87433Sdalcinl Newton method. 397071f87433Sdalcinl 39713f9fe445SBarry Smith Logically Collective on SNES 397271f87433Sdalcinl 397371f87433Sdalcinl Input Parameters: 397471f87433Sdalcinl + snes - SNES context 397571f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 397671f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 397771f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 397871f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 397971f87433Sdalcinl (0 <= gamma2 <= 1) 398071f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 398171f87433Sdalcinl . alpha2 - power for safeguard 398271f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 398371f87433Sdalcinl 398471f87433Sdalcinl Note: 398571f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 398671f87433Sdalcinl 398771f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 398871f87433Sdalcinl 398971f87433Sdalcinl Level: advanced 399071f87433Sdalcinl 399171f87433Sdalcinl Reference: 399271f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 399371f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 399471f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 399571f87433Sdalcinl 399671f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 399771f87433Sdalcinl 3998fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 399971f87433Sdalcinl @*/ 40007087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 400171f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 400271f87433Sdalcinl { 4003fa9f3622SBarry Smith SNESKSPEW *kctx; 400471f87433Sdalcinl PetscFunctionBegin; 40050700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4006fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4007e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 4008c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 4009c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 4010c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 4011c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 4012c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 4013c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 4014c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 401571f87433Sdalcinl 401671f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 401771f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 401871f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 401971f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 402071f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 402171f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 402271f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 402371f87433Sdalcinl 402471f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 4025e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 402671f87433Sdalcinl } 402771f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 4028e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 402971f87433Sdalcinl } 403071f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 4031e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 403271f87433Sdalcinl } 403371f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 4034e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 403571f87433Sdalcinl } 403671f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 4037e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 403871f87433Sdalcinl } 403971f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 4040e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 404171f87433Sdalcinl } 404271f87433Sdalcinl PetscFunctionReturn(0); 404371f87433Sdalcinl } 404471f87433Sdalcinl 404571f87433Sdalcinl #undef __FUNCT__ 4046fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 404771f87433Sdalcinl /*@ 4048fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 404971f87433Sdalcinl convergence criteria for the linear solvers within an inexact 405071f87433Sdalcinl Newton method. 405171f87433Sdalcinl 405271f87433Sdalcinl Not Collective 405371f87433Sdalcinl 405471f87433Sdalcinl Input Parameters: 405571f87433Sdalcinl snes - SNES context 405671f87433Sdalcinl 405771f87433Sdalcinl Output Parameters: 405871f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 405971f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 406071f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 406171f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 406271f87433Sdalcinl (0 <= gamma2 <= 1) 406371f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 406471f87433Sdalcinl . alpha2 - power for safeguard 406571f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 406671f87433Sdalcinl 406771f87433Sdalcinl Level: advanced 406871f87433Sdalcinl 406971f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 407071f87433Sdalcinl 4071fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 407271f87433Sdalcinl @*/ 40737087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 407471f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 407571f87433Sdalcinl { 4076fa9f3622SBarry Smith SNESKSPEW *kctx; 407771f87433Sdalcinl PetscFunctionBegin; 40780700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4079fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4080e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 408171f87433Sdalcinl if(version) *version = kctx->version; 408271f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 408371f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 408471f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 408571f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 408671f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 408771f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 408871f87433Sdalcinl PetscFunctionReturn(0); 408971f87433Sdalcinl } 409071f87433Sdalcinl 409171f87433Sdalcinl #undef __FUNCT__ 4092fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 4093fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 409471f87433Sdalcinl { 409571f87433Sdalcinl PetscErrorCode ierr; 4096fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 409771f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 409871f87433Sdalcinl 409971f87433Sdalcinl PetscFunctionBegin; 4100e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 410171f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 410271f87433Sdalcinl rtol = kctx->rtol_0; 410371f87433Sdalcinl } else { 410471f87433Sdalcinl if (kctx->version == 1) { 410571f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 410671f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 410771f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 410871f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 410971f87433Sdalcinl } else if (kctx->version == 2) { 411071f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 411171f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 411271f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 411371f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 411471f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 411571f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 411671f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 411771f87433Sdalcinl stol = PetscMax(rtol,stol); 411871f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 411971f87433Sdalcinl /* safeguard: avoid oversolving */ 412071f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 412171f87433Sdalcinl stol = PetscMax(rtol,stol); 412271f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 4123e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 412471f87433Sdalcinl } 412571f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 412671f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 412771f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 412871f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 412971f87433Sdalcinl PetscFunctionReturn(0); 413071f87433Sdalcinl } 413171f87433Sdalcinl 413271f87433Sdalcinl #undef __FUNCT__ 4133fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 4134fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 413571f87433Sdalcinl { 413671f87433Sdalcinl PetscErrorCode ierr; 4137fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 413871f87433Sdalcinl PCSide pcside; 413971f87433Sdalcinl Vec lres; 414071f87433Sdalcinl 414171f87433Sdalcinl PetscFunctionBegin; 4142e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 414371f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 414471f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 414571f87433Sdalcinl if (kctx->version == 1) { 4146b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 414771f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 414871f87433Sdalcinl /* KSP residual is true linear residual */ 414971f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 415071f87433Sdalcinl } else { 415171f87433Sdalcinl /* KSP residual is preconditioned residual */ 415271f87433Sdalcinl /* compute true linear residual norm */ 415371f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 415471f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 415571f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 415671f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 41576bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 415871f87433Sdalcinl } 415971f87433Sdalcinl } 416071f87433Sdalcinl PetscFunctionReturn(0); 416171f87433Sdalcinl } 416271f87433Sdalcinl 416371f87433Sdalcinl #undef __FUNCT__ 416471f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 416571f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 416671f87433Sdalcinl { 416771f87433Sdalcinl PetscErrorCode ierr; 416871f87433Sdalcinl 416971f87433Sdalcinl PetscFunctionBegin; 4170fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 417171f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 4172fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 417371f87433Sdalcinl PetscFunctionReturn(0); 417471f87433Sdalcinl } 41756c699258SBarry Smith 41766c699258SBarry Smith #undef __FUNCT__ 41776c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 41786c699258SBarry Smith /*@ 41796c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 41806c699258SBarry Smith 41813f9fe445SBarry Smith Logically Collective on SNES 41826c699258SBarry Smith 41836c699258SBarry Smith Input Parameters: 41846c699258SBarry Smith + snes - the preconditioner context 41856c699258SBarry Smith - dm - the dm 41866c699258SBarry Smith 41876c699258SBarry Smith Level: intermediate 41886c699258SBarry Smith 41896c699258SBarry Smith 41906c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 41916c699258SBarry Smith @*/ 41927087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 41936c699258SBarry Smith { 41946c699258SBarry Smith PetscErrorCode ierr; 4195345fed2cSBarry Smith KSP ksp; 41966cab3a1bSJed Brown SNESDM sdm; 41976c699258SBarry Smith 41986c699258SBarry Smith PetscFunctionBegin; 41990700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4200d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 42016cab3a1bSJed Brown if (snes->dm) { /* Move the SNESDM context over to the new DM unless the new DM already has one */ 42026cab3a1bSJed Brown PetscContainer oldcontainer,container; 42036cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 42046cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr); 42056cab3a1bSJed Brown if (oldcontainer && !container) { 42066cab3a1bSJed Brown ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr); 42076cab3a1bSJed Brown ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr); 42086cab3a1bSJed Brown if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */ 42096cab3a1bSJed Brown sdm->originaldm = dm; 42106cab3a1bSJed Brown } 42116cab3a1bSJed Brown } 42126bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 42136cab3a1bSJed Brown } 42146c699258SBarry Smith snes->dm = dm; 4215345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4216345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4217f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 42182c155ee1SBarry Smith if (snes->pc) { 42192c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 42202c155ee1SBarry Smith } 42216c699258SBarry Smith PetscFunctionReturn(0); 42226c699258SBarry Smith } 42236c699258SBarry Smith 42246c699258SBarry Smith #undef __FUNCT__ 42256c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 42266c699258SBarry Smith /*@ 42276c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 42286c699258SBarry Smith 42293f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 42306c699258SBarry Smith 42316c699258SBarry Smith Input Parameter: 42326c699258SBarry Smith . snes - the preconditioner context 42336c699258SBarry Smith 42346c699258SBarry Smith Output Parameter: 42356c699258SBarry Smith . dm - the dm 42366c699258SBarry Smith 42376c699258SBarry Smith Level: intermediate 42386c699258SBarry Smith 42396c699258SBarry Smith 42406c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 42416c699258SBarry Smith @*/ 42427087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 42436c699258SBarry Smith { 42446cab3a1bSJed Brown PetscErrorCode ierr; 42456cab3a1bSJed Brown 42466c699258SBarry Smith PetscFunctionBegin; 42470700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 42486cab3a1bSJed Brown if (!snes->dm) { 42496cab3a1bSJed Brown ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr); 42506cab3a1bSJed Brown } 42516c699258SBarry Smith *dm = snes->dm; 42526c699258SBarry Smith PetscFunctionReturn(0); 42536c699258SBarry Smith } 42540807856dSBarry Smith 425531823bd8SMatthew G Knepley #undef __FUNCT__ 425631823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 425731823bd8SMatthew G Knepley /*@ 4258fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 425931823bd8SMatthew G Knepley 426031823bd8SMatthew G Knepley Collective on SNES 426131823bd8SMatthew G Knepley 426231823bd8SMatthew G Knepley Input Parameters: 426331823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 426431823bd8SMatthew G Knepley - pc - the preconditioner object 426531823bd8SMatthew G Knepley 426631823bd8SMatthew G Knepley Notes: 426731823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 426831823bd8SMatthew G Knepley to configure it using the API). 426931823bd8SMatthew G Knepley 427031823bd8SMatthew G Knepley Level: developer 427131823bd8SMatthew G Knepley 427231823bd8SMatthew G Knepley .keywords: SNES, set, precondition 427331823bd8SMatthew G Knepley .seealso: SNESGetPC() 427431823bd8SMatthew G Knepley @*/ 427531823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 427631823bd8SMatthew G Knepley { 427731823bd8SMatthew G Knepley PetscErrorCode ierr; 427831823bd8SMatthew G Knepley 427931823bd8SMatthew G Knepley PetscFunctionBegin; 428031823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 428131823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 428231823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 428331823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4284bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 428531823bd8SMatthew G Knepley snes->pc = pc; 428631823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 428731823bd8SMatthew G Knepley PetscFunctionReturn(0); 428831823bd8SMatthew G Knepley } 428931823bd8SMatthew G Knepley 429031823bd8SMatthew G Knepley #undef __FUNCT__ 429131823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 429231823bd8SMatthew G Knepley /*@ 4293fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 429431823bd8SMatthew G Knepley 429531823bd8SMatthew G Knepley Not Collective 429631823bd8SMatthew G Knepley 429731823bd8SMatthew G Knepley Input Parameter: 429831823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 429931823bd8SMatthew G Knepley 430031823bd8SMatthew G Knepley Output Parameter: 430131823bd8SMatthew G Knepley . pc - preconditioner context 430231823bd8SMatthew G Knepley 430331823bd8SMatthew G Knepley Level: developer 430431823bd8SMatthew G Knepley 430531823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 430631823bd8SMatthew G Knepley .seealso: SNESSetPC() 430731823bd8SMatthew G Knepley @*/ 430831823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 430931823bd8SMatthew G Knepley { 431031823bd8SMatthew G Knepley PetscErrorCode ierr; 431131823bd8SMatthew G Knepley 431231823bd8SMatthew G Knepley PetscFunctionBegin; 431331823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 431431823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 431531823bd8SMatthew G Knepley if (!snes->pc) { 431631823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr); 43174a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr); 431831823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 431931823bd8SMatthew G Knepley } 432031823bd8SMatthew G Knepley *pc = snes->pc; 432131823bd8SMatthew G Knepley PetscFunctionReturn(0); 432231823bd8SMatthew G Knepley } 432331823bd8SMatthew G Knepley 43249e764e56SPeter Brune #undef __FUNCT__ 4325f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch" 43269e764e56SPeter Brune /*@ 4327f1c6b773SPeter Brune SNESSetSNESLineSearch - Sets the linesearch. 43289e764e56SPeter Brune 43299e764e56SPeter Brune Collective on SNES 43309e764e56SPeter Brune 43319e764e56SPeter Brune Input Parameters: 43329e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 43339e764e56SPeter Brune - linesearch - the linesearch object 43349e764e56SPeter Brune 43359e764e56SPeter Brune Notes: 4336f1c6b773SPeter Brune Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example, 43379e764e56SPeter Brune to configure it using the API). 43389e764e56SPeter Brune 43399e764e56SPeter Brune Level: developer 43409e764e56SPeter Brune 43419e764e56SPeter Brune .keywords: SNES, set, linesearch 4342f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch() 43439e764e56SPeter Brune @*/ 4344f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch) 43459e764e56SPeter Brune { 43469e764e56SPeter Brune PetscErrorCode ierr; 43479e764e56SPeter Brune 43489e764e56SPeter Brune PetscFunctionBegin; 43499e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4350f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 43519e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 43529e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 4353f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 43549e764e56SPeter Brune snes->linesearch = linesearch; 43559e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 43569e764e56SPeter Brune PetscFunctionReturn(0); 43579e764e56SPeter Brune } 43589e764e56SPeter Brune 43599e764e56SPeter Brune #undef __FUNCT__ 4360f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch" 4361ea5d4fccSPeter Brune /*@C 4362f1c6b773SPeter Brune SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch(). 43639e764e56SPeter Brune 43649e764e56SPeter Brune Not Collective 43659e764e56SPeter Brune 43669e764e56SPeter Brune Input Parameter: 43679e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 43689e764e56SPeter Brune 43699e764e56SPeter Brune Output Parameter: 43709e764e56SPeter Brune . linesearch - linesearch context 43719e764e56SPeter Brune 43729e764e56SPeter Brune Level: developer 43739e764e56SPeter Brune 43749e764e56SPeter Brune .keywords: SNES, get, linesearch 4375f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch() 43769e764e56SPeter Brune @*/ 4377f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch) 43789e764e56SPeter Brune { 43799e764e56SPeter Brune PetscErrorCode ierr; 43809e764e56SPeter Brune const char *optionsprefix; 43819e764e56SPeter Brune 43829e764e56SPeter Brune PetscFunctionBegin; 43839e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 43849e764e56SPeter Brune PetscValidPointer(linesearch, 2); 43859e764e56SPeter Brune if (!snes->linesearch) { 43869e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 4387f1c6b773SPeter Brune ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr); 4388f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 4389b1dca40bSPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 43909e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 43919e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 43929e764e56SPeter Brune } 43939e764e56SPeter Brune *linesearch = snes->linesearch; 43949e764e56SPeter Brune PetscFunctionReturn(0); 43959e764e56SPeter Brune } 43969e764e56SPeter Brune 439769b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4398c6db04a5SJed Brown #include <mex.h> 439969b4f73cSBarry Smith 44008f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 44018f6e6473SBarry Smith 44020807856dSBarry Smith #undef __FUNCT__ 44030807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 44040807856dSBarry Smith /* 44050807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 44060807856dSBarry Smith SNESSetFunctionMatlab(). 44070807856dSBarry Smith 44080807856dSBarry Smith Collective on SNES 44090807856dSBarry Smith 44100807856dSBarry Smith Input Parameters: 44110807856dSBarry Smith + snes - the SNES context 44120807856dSBarry Smith - x - input vector 44130807856dSBarry Smith 44140807856dSBarry Smith Output Parameter: 44150807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 44160807856dSBarry Smith 44170807856dSBarry Smith Notes: 44180807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 44190807856dSBarry Smith implementations, so most users would not generally call this routine 44200807856dSBarry Smith themselves. 44210807856dSBarry Smith 44220807856dSBarry Smith Level: developer 44230807856dSBarry Smith 44240807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 44250807856dSBarry Smith 44260807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 442761b2408cSBarry Smith */ 44287087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 44290807856dSBarry Smith { 4430e650e774SBarry Smith PetscErrorCode ierr; 44318f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 44328f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 44338f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 443491621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 4435e650e774SBarry Smith 44360807856dSBarry Smith PetscFunctionBegin; 44370807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 44380807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 44390807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 44400807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 44410807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 44420807856dSBarry Smith 44430807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 4444e650e774SBarry Smith 444591621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4446e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4447e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 444891621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 444991621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 445091621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 44518f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 44528f6e6473SBarry Smith prhs[4] = sctx->ctx; 4453b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 4454e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4455e650e774SBarry Smith mxDestroyArray(prhs[0]); 4456e650e774SBarry Smith mxDestroyArray(prhs[1]); 4457e650e774SBarry Smith mxDestroyArray(prhs[2]); 44588f6e6473SBarry Smith mxDestroyArray(prhs[3]); 4459e650e774SBarry Smith mxDestroyArray(plhs[0]); 44600807856dSBarry Smith PetscFunctionReturn(0); 44610807856dSBarry Smith } 44620807856dSBarry Smith 44630807856dSBarry Smith 44640807856dSBarry Smith #undef __FUNCT__ 44650807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 446661b2408cSBarry Smith /* 44670807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 44680807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4469e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 44700807856dSBarry Smith 44710807856dSBarry Smith Logically Collective on SNES 44720807856dSBarry Smith 44730807856dSBarry Smith Input Parameters: 44740807856dSBarry Smith + snes - the SNES context 44750807856dSBarry Smith . r - vector to store function value 44760807856dSBarry Smith - func - function evaluation routine 44770807856dSBarry Smith 44780807856dSBarry Smith Calling sequence of func: 447961b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 44800807856dSBarry Smith 44810807856dSBarry Smith 44820807856dSBarry Smith Notes: 44830807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 44840807856dSBarry Smith $ f'(x) x = -f(x), 44850807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 44860807856dSBarry Smith 44870807856dSBarry Smith Level: beginner 44880807856dSBarry Smith 44890807856dSBarry Smith .keywords: SNES, nonlinear, set, function 44900807856dSBarry Smith 44910807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 449261b2408cSBarry Smith */ 44937087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 44940807856dSBarry Smith { 44950807856dSBarry Smith PetscErrorCode ierr; 44968f6e6473SBarry Smith SNESMatlabContext *sctx; 44970807856dSBarry Smith 44980807856dSBarry Smith PetscFunctionBegin; 44998f6e6473SBarry Smith /* currently sctx is memory bleed */ 45008f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 45018f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 45028f6e6473SBarry Smith /* 45038f6e6473SBarry Smith This should work, but it doesn't 45048f6e6473SBarry Smith sctx->ctx = ctx; 45058f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 45068f6e6473SBarry Smith */ 45078f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 45088f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 45090807856dSBarry Smith PetscFunctionReturn(0); 45100807856dSBarry Smith } 451169b4f73cSBarry Smith 451261b2408cSBarry Smith #undef __FUNCT__ 451361b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 451461b2408cSBarry Smith /* 451561b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 451661b2408cSBarry Smith SNESSetJacobianMatlab(). 451761b2408cSBarry Smith 451861b2408cSBarry Smith Collective on SNES 451961b2408cSBarry Smith 452061b2408cSBarry Smith Input Parameters: 452161b2408cSBarry Smith + snes - the SNES context 452261b2408cSBarry Smith . x - input vector 452361b2408cSBarry Smith . A, B - the matrices 452461b2408cSBarry Smith - ctx - user context 452561b2408cSBarry Smith 452661b2408cSBarry Smith Output Parameter: 452761b2408cSBarry Smith . flag - structure of the matrix 452861b2408cSBarry Smith 452961b2408cSBarry Smith Level: developer 453061b2408cSBarry Smith 453161b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 453261b2408cSBarry Smith 453361b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 453461b2408cSBarry Smith @*/ 45357087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 453661b2408cSBarry Smith { 453761b2408cSBarry Smith PetscErrorCode ierr; 453861b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 453961b2408cSBarry Smith int nlhs = 2,nrhs = 6; 454061b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 454161b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 454261b2408cSBarry Smith 454361b2408cSBarry Smith PetscFunctionBegin; 454461b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 454561b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 454661b2408cSBarry Smith 454761b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 454861b2408cSBarry Smith 454961b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 455061b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 455161b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 455261b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 455361b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 455461b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 455561b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 455661b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 455761b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 455861b2408cSBarry Smith prhs[5] = sctx->ctx; 4559b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 456061b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 456161b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 456261b2408cSBarry Smith mxDestroyArray(prhs[0]); 456361b2408cSBarry Smith mxDestroyArray(prhs[1]); 456461b2408cSBarry Smith mxDestroyArray(prhs[2]); 456561b2408cSBarry Smith mxDestroyArray(prhs[3]); 456661b2408cSBarry Smith mxDestroyArray(prhs[4]); 456761b2408cSBarry Smith mxDestroyArray(plhs[0]); 456861b2408cSBarry Smith mxDestroyArray(plhs[1]); 456961b2408cSBarry Smith PetscFunctionReturn(0); 457061b2408cSBarry Smith } 457161b2408cSBarry Smith 457261b2408cSBarry Smith 457361b2408cSBarry Smith #undef __FUNCT__ 457461b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 457561b2408cSBarry Smith /* 457661b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 457761b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4578e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 457961b2408cSBarry Smith 458061b2408cSBarry Smith Logically Collective on SNES 458161b2408cSBarry Smith 458261b2408cSBarry Smith Input Parameters: 458361b2408cSBarry Smith + snes - the SNES context 458461b2408cSBarry Smith . A,B - Jacobian matrices 458561b2408cSBarry Smith . func - function evaluation routine 458661b2408cSBarry Smith - ctx - user context 458761b2408cSBarry Smith 458861b2408cSBarry Smith Calling sequence of func: 458961b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 459061b2408cSBarry Smith 459161b2408cSBarry Smith 459261b2408cSBarry Smith Level: developer 459361b2408cSBarry Smith 459461b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 459561b2408cSBarry Smith 459661b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 459761b2408cSBarry Smith */ 45987087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 459961b2408cSBarry Smith { 460061b2408cSBarry Smith PetscErrorCode ierr; 460161b2408cSBarry Smith SNESMatlabContext *sctx; 460261b2408cSBarry Smith 460361b2408cSBarry Smith PetscFunctionBegin; 460461b2408cSBarry Smith /* currently sctx is memory bleed */ 460561b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 460661b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 460761b2408cSBarry Smith /* 460861b2408cSBarry Smith This should work, but it doesn't 460961b2408cSBarry Smith sctx->ctx = ctx; 461061b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 461161b2408cSBarry Smith */ 461261b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 461361b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 461461b2408cSBarry Smith PetscFunctionReturn(0); 461561b2408cSBarry Smith } 461669b4f73cSBarry Smith 4617f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4618f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4619f9eb7ae2SShri Abhyankar /* 4620f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4621f9eb7ae2SShri Abhyankar 4622f9eb7ae2SShri Abhyankar Collective on SNES 4623f9eb7ae2SShri Abhyankar 4624f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4625f9eb7ae2SShri Abhyankar @*/ 46267087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4627f9eb7ae2SShri Abhyankar { 4628f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 462948f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4630f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4631f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4632f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4633f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4634f9eb7ae2SShri Abhyankar 4635f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4636f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4637f9eb7ae2SShri Abhyankar 4638f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4639f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4640f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4641f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4642f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4643f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4644f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4645f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4646f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4647f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4648f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4649f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4650f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4651f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4652f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4653f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4654f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4655f9eb7ae2SShri Abhyankar } 4656f9eb7ae2SShri Abhyankar 4657f9eb7ae2SShri Abhyankar 4658f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4659f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4660f9eb7ae2SShri Abhyankar /* 4661e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4662f9eb7ae2SShri Abhyankar 4663f9eb7ae2SShri Abhyankar Level: developer 4664f9eb7ae2SShri Abhyankar 4665f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4666f9eb7ae2SShri Abhyankar 4667f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4668f9eb7ae2SShri Abhyankar */ 46697087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4670f9eb7ae2SShri Abhyankar { 4671f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4672f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4673f9eb7ae2SShri Abhyankar 4674f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4675f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4676f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4677f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4678f9eb7ae2SShri Abhyankar /* 4679f9eb7ae2SShri Abhyankar This should work, but it doesn't 4680f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4681f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4682f9eb7ae2SShri Abhyankar */ 4683f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4684f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4685f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4686f9eb7ae2SShri Abhyankar } 4687f9eb7ae2SShri Abhyankar 468869b4f73cSBarry Smith #endif 4689