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); 704*534ebe21SPeter Brune ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); 7054a0c5b0cSMatthew G Knepley ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 7064a0c5b0cSMatthew G Knepley } 7073a40ed3dSBarry Smith PetscFunctionReturn(0); 7089b94acceSBarry Smith } 7099b94acceSBarry Smith 710d25893d9SBarry Smith #undef __FUNCT__ 711d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 712d25893d9SBarry Smith /*@ 713d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 714d25893d9SBarry Smith the nonlinear solvers. 715d25893d9SBarry Smith 716d25893d9SBarry Smith Logically Collective on SNES 717d25893d9SBarry Smith 718d25893d9SBarry Smith Input Parameters: 719d25893d9SBarry Smith + snes - the SNES context 720d25893d9SBarry Smith . compute - function to compute the context 721d25893d9SBarry Smith - destroy - function to destroy the context 722d25893d9SBarry Smith 723d25893d9SBarry Smith Level: intermediate 724d25893d9SBarry Smith 725d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 726d25893d9SBarry Smith 727d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 728d25893d9SBarry Smith @*/ 729d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 730d25893d9SBarry Smith { 731d25893d9SBarry Smith PetscFunctionBegin; 732d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 733d25893d9SBarry Smith snes->ops->usercompute = compute; 734d25893d9SBarry Smith snes->ops->userdestroy = destroy; 735d25893d9SBarry Smith PetscFunctionReturn(0); 736d25893d9SBarry Smith } 737a847f771SSatish Balay 7384a2ae208SSatish Balay #undef __FUNCT__ 7394a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 740b07ff414SBarry Smith /*@ 7419b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 7429b94acceSBarry Smith the nonlinear solvers. 7439b94acceSBarry Smith 7443f9fe445SBarry Smith Logically Collective on SNES 745fee21e36SBarry Smith 746c7afd0dbSLois Curfman McInnes Input Parameters: 747c7afd0dbSLois Curfman McInnes + snes - the SNES context 748c7afd0dbSLois Curfman McInnes - usrP - optional user context 749c7afd0dbSLois Curfman McInnes 75036851e7fSLois Curfman McInnes Level: intermediate 75136851e7fSLois Curfman McInnes 7529b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 7539b94acceSBarry Smith 754d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext() 7559b94acceSBarry Smith @*/ 7567087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 7579b94acceSBarry Smith { 7581b2093e4SBarry Smith PetscErrorCode ierr; 759b07ff414SBarry Smith KSP ksp; 7601b2093e4SBarry Smith 7613a40ed3dSBarry Smith PetscFunctionBegin; 7620700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 763b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 764b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 7659b94acceSBarry Smith snes->user = usrP; 7663a40ed3dSBarry Smith PetscFunctionReturn(0); 7679b94acceSBarry Smith } 76874679c65SBarry Smith 7694a2ae208SSatish Balay #undef __FUNCT__ 7704a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 771b07ff414SBarry Smith /*@ 7729b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 7739b94acceSBarry Smith nonlinear solvers. 7749b94acceSBarry Smith 775c7afd0dbSLois Curfman McInnes Not Collective 776c7afd0dbSLois Curfman McInnes 7779b94acceSBarry Smith Input Parameter: 7789b94acceSBarry Smith . snes - SNES context 7799b94acceSBarry Smith 7809b94acceSBarry Smith Output Parameter: 7819b94acceSBarry Smith . usrP - user context 7829b94acceSBarry Smith 78336851e7fSLois Curfman McInnes Level: intermediate 78436851e7fSLois Curfman McInnes 7859b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 7869b94acceSBarry Smith 7879b94acceSBarry Smith .seealso: SNESSetApplicationContext() 7889b94acceSBarry Smith @*/ 789e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 7909b94acceSBarry Smith { 7913a40ed3dSBarry Smith PetscFunctionBegin; 7920700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 793e71120c6SJed Brown *(void**)usrP = snes->user; 7943a40ed3dSBarry Smith PetscFunctionReturn(0); 7959b94acceSBarry Smith } 79674679c65SBarry Smith 7974a2ae208SSatish Balay #undef __FUNCT__ 7984a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 7999b94acceSBarry Smith /*@ 800c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 801c8228a4eSBarry Smith at this time. 8029b94acceSBarry Smith 803c7afd0dbSLois Curfman McInnes Not Collective 804c7afd0dbSLois Curfman McInnes 8059b94acceSBarry Smith Input Parameter: 8069b94acceSBarry Smith . snes - SNES context 8079b94acceSBarry Smith 8089b94acceSBarry Smith Output Parameter: 8099b94acceSBarry Smith . iter - iteration number 8109b94acceSBarry Smith 811c8228a4eSBarry Smith Notes: 812c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 813c8228a4eSBarry Smith 814c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 81508405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 81608405cd6SLois Curfman McInnes .vb 81708405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 81808405cd6SLois Curfman McInnes if (!(it % 2)) { 81908405cd6SLois Curfman McInnes [compute Jacobian here] 82008405cd6SLois Curfman McInnes } 82108405cd6SLois Curfman McInnes .ve 822c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 82308405cd6SLois Curfman McInnes recomputed every second SNES iteration. 824c8228a4eSBarry Smith 82536851e7fSLois Curfman McInnes Level: intermediate 82636851e7fSLois Curfman McInnes 8272b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 8282b668275SBarry Smith 829b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 8309b94acceSBarry Smith @*/ 8317087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 8329b94acceSBarry Smith { 8333a40ed3dSBarry Smith PetscFunctionBegin; 8340700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8354482741eSBarry Smith PetscValidIntPointer(iter,2); 8369b94acceSBarry Smith *iter = snes->iter; 8373a40ed3dSBarry Smith PetscFunctionReturn(0); 8389b94acceSBarry Smith } 83974679c65SBarry Smith 8404a2ae208SSatish Balay #undef __FUNCT__ 841360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber" 842360c497dSPeter Brune /*@ 843360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 844360c497dSPeter Brune 845360c497dSPeter Brune Not Collective 846360c497dSPeter Brune 847360c497dSPeter Brune Input Parameter: 848360c497dSPeter Brune . snes - SNES context 849360c497dSPeter Brune . iter - iteration number 850360c497dSPeter Brune 851360c497dSPeter Brune Level: developer 852360c497dSPeter Brune 853360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number, 854360c497dSPeter Brune 855360c497dSPeter Brune .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 856360c497dSPeter Brune @*/ 857360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 858360c497dSPeter Brune { 859360c497dSPeter Brune PetscErrorCode ierr; 860360c497dSPeter Brune 861360c497dSPeter Brune PetscFunctionBegin; 862360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 863360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 864360c497dSPeter Brune snes->iter = iter; 865360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 866360c497dSPeter Brune PetscFunctionReturn(0); 867360c497dSPeter Brune } 868360c497dSPeter Brune 869360c497dSPeter Brune #undef __FUNCT__ 8704a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 8719b94acceSBarry Smith /*@ 8729b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 8739b94acceSBarry Smith with SNESSSetFunction(). 8749b94acceSBarry Smith 875c7afd0dbSLois Curfman McInnes Collective on SNES 876c7afd0dbSLois Curfman McInnes 8779b94acceSBarry Smith Input Parameter: 8789b94acceSBarry Smith . snes - SNES context 8799b94acceSBarry Smith 8809b94acceSBarry Smith Output Parameter: 8819b94acceSBarry Smith . fnorm - 2-norm of function 8829b94acceSBarry Smith 88336851e7fSLois Curfman McInnes Level: intermediate 88436851e7fSLois Curfman McInnes 8859b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 886a86d99e1SLois Curfman McInnes 887b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 8889b94acceSBarry Smith @*/ 8897087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 8909b94acceSBarry Smith { 8913a40ed3dSBarry Smith PetscFunctionBegin; 8920700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8934482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 8949b94acceSBarry Smith *fnorm = snes->norm; 8953a40ed3dSBarry Smith PetscFunctionReturn(0); 8969b94acceSBarry Smith } 89774679c65SBarry Smith 898360c497dSPeter Brune 899360c497dSPeter Brune #undef __FUNCT__ 900360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm" 901360c497dSPeter Brune /*@ 902360c497dSPeter Brune SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm(). 903360c497dSPeter Brune 904360c497dSPeter Brune Collective on SNES 905360c497dSPeter Brune 906360c497dSPeter Brune Input Parameter: 907360c497dSPeter Brune . snes - SNES context 908360c497dSPeter Brune . fnorm - 2-norm of function 909360c497dSPeter Brune 910360c497dSPeter Brune Level: developer 911360c497dSPeter Brune 912360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm 913360c497dSPeter Brune 914360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm(). 915360c497dSPeter Brune @*/ 916360c497dSPeter Brune PetscErrorCode SNESSetFunctionNorm(SNES snes,PetscReal fnorm) 917360c497dSPeter Brune { 918360c497dSPeter Brune 919360c497dSPeter Brune PetscErrorCode ierr; 920360c497dSPeter Brune 921360c497dSPeter Brune PetscFunctionBegin; 922360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 923360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 924360c497dSPeter Brune snes->norm = fnorm; 925360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 926360c497dSPeter Brune PetscFunctionReturn(0); 927360c497dSPeter Brune } 928360c497dSPeter Brune 9294a2ae208SSatish Balay #undef __FUNCT__ 930b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 9319b94acceSBarry Smith /*@ 932b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 9339b94acceSBarry Smith attempted by the nonlinear solver. 9349b94acceSBarry Smith 935c7afd0dbSLois Curfman McInnes Not Collective 936c7afd0dbSLois Curfman McInnes 9379b94acceSBarry Smith Input Parameter: 9389b94acceSBarry Smith . snes - SNES context 9399b94acceSBarry Smith 9409b94acceSBarry Smith Output Parameter: 9419b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 9429b94acceSBarry Smith 943c96a6f78SLois Curfman McInnes Notes: 944c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 945c96a6f78SLois Curfman McInnes 94636851e7fSLois Curfman McInnes Level: intermediate 94736851e7fSLois Curfman McInnes 9489b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 94958ebbce7SBarry Smith 950e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 95158ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 9529b94acceSBarry Smith @*/ 9537087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 9549b94acceSBarry Smith { 9553a40ed3dSBarry Smith PetscFunctionBegin; 9560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9574482741eSBarry Smith PetscValidIntPointer(nfails,2); 95850ffb88aSMatthew Knepley *nfails = snes->numFailures; 95950ffb88aSMatthew Knepley PetscFunctionReturn(0); 96050ffb88aSMatthew Knepley } 96150ffb88aSMatthew Knepley 96250ffb88aSMatthew Knepley #undef __FUNCT__ 963b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 96450ffb88aSMatthew Knepley /*@ 965b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 96650ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 96750ffb88aSMatthew Knepley 96850ffb88aSMatthew Knepley Not Collective 96950ffb88aSMatthew Knepley 97050ffb88aSMatthew Knepley Input Parameters: 97150ffb88aSMatthew Knepley + snes - SNES context 97250ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 97350ffb88aSMatthew Knepley 97450ffb88aSMatthew Knepley Level: intermediate 97550ffb88aSMatthew Knepley 97650ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 97758ebbce7SBarry Smith 978e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 97958ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 98050ffb88aSMatthew Knepley @*/ 9817087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 98250ffb88aSMatthew Knepley { 98350ffb88aSMatthew Knepley PetscFunctionBegin; 9840700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 98550ffb88aSMatthew Knepley snes->maxFailures = maxFails; 98650ffb88aSMatthew Knepley PetscFunctionReturn(0); 98750ffb88aSMatthew Knepley } 98850ffb88aSMatthew Knepley 98950ffb88aSMatthew Knepley #undef __FUNCT__ 990b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 99150ffb88aSMatthew Knepley /*@ 992b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 99350ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 99450ffb88aSMatthew Knepley 99550ffb88aSMatthew Knepley Not Collective 99650ffb88aSMatthew Knepley 99750ffb88aSMatthew Knepley Input Parameter: 99850ffb88aSMatthew Knepley . snes - SNES context 99950ffb88aSMatthew Knepley 100050ffb88aSMatthew Knepley Output Parameter: 100150ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 100250ffb88aSMatthew Knepley 100350ffb88aSMatthew Knepley Level: intermediate 100450ffb88aSMatthew Knepley 100550ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 100658ebbce7SBarry Smith 1007e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 100858ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 100958ebbce7SBarry Smith 101050ffb88aSMatthew Knepley @*/ 10117087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 101250ffb88aSMatthew Knepley { 101350ffb88aSMatthew Knepley PetscFunctionBegin; 10140700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10154482741eSBarry Smith PetscValidIntPointer(maxFails,2); 101650ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 10173a40ed3dSBarry Smith PetscFunctionReturn(0); 10189b94acceSBarry Smith } 1019a847f771SSatish Balay 10204a2ae208SSatish Balay #undef __FUNCT__ 10212541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 10222541af92SBarry Smith /*@ 10232541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 10242541af92SBarry Smith done by SNES. 10252541af92SBarry Smith 10262541af92SBarry Smith Not Collective 10272541af92SBarry Smith 10282541af92SBarry Smith Input Parameter: 10292541af92SBarry Smith . snes - SNES context 10302541af92SBarry Smith 10312541af92SBarry Smith Output Parameter: 10322541af92SBarry Smith . nfuncs - number of evaluations 10332541af92SBarry Smith 10342541af92SBarry Smith Level: intermediate 10352541af92SBarry Smith 10362541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 103758ebbce7SBarry Smith 1038e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 10392541af92SBarry Smith @*/ 10407087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 10412541af92SBarry Smith { 10422541af92SBarry Smith PetscFunctionBegin; 10430700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10442541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 10452541af92SBarry Smith *nfuncs = snes->nfuncs; 10462541af92SBarry Smith PetscFunctionReturn(0); 10472541af92SBarry Smith } 10482541af92SBarry Smith 10492541af92SBarry Smith #undef __FUNCT__ 10503d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 10513d4c4710SBarry Smith /*@ 10523d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 10533d4c4710SBarry Smith linear solvers. 10543d4c4710SBarry Smith 10553d4c4710SBarry Smith Not Collective 10563d4c4710SBarry Smith 10573d4c4710SBarry Smith Input Parameter: 10583d4c4710SBarry Smith . snes - SNES context 10593d4c4710SBarry Smith 10603d4c4710SBarry Smith Output Parameter: 10613d4c4710SBarry Smith . nfails - number of failed solves 10623d4c4710SBarry Smith 10633d4c4710SBarry Smith Notes: 10643d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 10653d4c4710SBarry Smith 10663d4c4710SBarry Smith Level: intermediate 10673d4c4710SBarry Smith 10683d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 106958ebbce7SBarry Smith 1070e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 10713d4c4710SBarry Smith @*/ 10727087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 10733d4c4710SBarry Smith { 10743d4c4710SBarry Smith PetscFunctionBegin; 10750700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10763d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 10773d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 10783d4c4710SBarry Smith PetscFunctionReturn(0); 10793d4c4710SBarry Smith } 10803d4c4710SBarry Smith 10813d4c4710SBarry Smith #undef __FUNCT__ 10823d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 10833d4c4710SBarry Smith /*@ 10843d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 10853d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 10863d4c4710SBarry Smith 10873f9fe445SBarry Smith Logically Collective on SNES 10883d4c4710SBarry Smith 10893d4c4710SBarry Smith Input Parameters: 10903d4c4710SBarry Smith + snes - SNES context 10913d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 10923d4c4710SBarry Smith 10933d4c4710SBarry Smith Level: intermediate 10943d4c4710SBarry Smith 1095a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 10963d4c4710SBarry Smith 10973d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 10983d4c4710SBarry Smith 109958ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 11003d4c4710SBarry Smith @*/ 11017087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 11023d4c4710SBarry Smith { 11033d4c4710SBarry Smith PetscFunctionBegin; 11040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1105c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 11063d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 11073d4c4710SBarry Smith PetscFunctionReturn(0); 11083d4c4710SBarry Smith } 11093d4c4710SBarry Smith 11103d4c4710SBarry Smith #undef __FUNCT__ 11113d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 11123d4c4710SBarry Smith /*@ 11133d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 11143d4c4710SBarry Smith are allowed before SNES terminates 11153d4c4710SBarry Smith 11163d4c4710SBarry Smith Not Collective 11173d4c4710SBarry Smith 11183d4c4710SBarry Smith Input Parameter: 11193d4c4710SBarry Smith . snes - SNES context 11203d4c4710SBarry Smith 11213d4c4710SBarry Smith Output Parameter: 11223d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 11233d4c4710SBarry Smith 11243d4c4710SBarry Smith Level: intermediate 11253d4c4710SBarry Smith 11263d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 11273d4c4710SBarry Smith 11283d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 11293d4c4710SBarry Smith 1130e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 11313d4c4710SBarry Smith @*/ 11327087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 11333d4c4710SBarry Smith { 11343d4c4710SBarry Smith PetscFunctionBegin; 11350700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11363d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 11373d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 11383d4c4710SBarry Smith PetscFunctionReturn(0); 11393d4c4710SBarry Smith } 11403d4c4710SBarry Smith 11413d4c4710SBarry Smith #undef __FUNCT__ 1142b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 1143c96a6f78SLois Curfman McInnes /*@ 1144b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1145c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1146c96a6f78SLois Curfman McInnes 1147c7afd0dbSLois Curfman McInnes Not Collective 1148c7afd0dbSLois Curfman McInnes 1149c96a6f78SLois Curfman McInnes Input Parameter: 1150c96a6f78SLois Curfman McInnes . snes - SNES context 1151c96a6f78SLois Curfman McInnes 1152c96a6f78SLois Curfman McInnes Output Parameter: 1153c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1154c96a6f78SLois Curfman McInnes 1155c96a6f78SLois Curfman McInnes Notes: 1156c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1157c96a6f78SLois Curfman McInnes 115836851e7fSLois Curfman McInnes Level: intermediate 115936851e7fSLois Curfman McInnes 1160c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 11612b668275SBarry Smith 11628c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 1163c96a6f78SLois Curfman McInnes @*/ 11647087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 1165c96a6f78SLois Curfman McInnes { 11663a40ed3dSBarry Smith PetscFunctionBegin; 11670700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11684482741eSBarry Smith PetscValidIntPointer(lits,2); 1169c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 11703a40ed3dSBarry Smith PetscFunctionReturn(0); 1171c96a6f78SLois Curfman McInnes } 1172c96a6f78SLois Curfman McInnes 11734a2ae208SSatish Balay #undef __FUNCT__ 117494b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 117552baeb72SSatish Balay /*@ 117694b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 11779b94acceSBarry Smith 117894b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 1179c7afd0dbSLois Curfman McInnes 11809b94acceSBarry Smith Input Parameter: 11819b94acceSBarry Smith . snes - the SNES context 11829b94acceSBarry Smith 11839b94acceSBarry Smith Output Parameter: 118494b7f48cSBarry Smith . ksp - the KSP context 11859b94acceSBarry Smith 11869b94acceSBarry Smith Notes: 118794b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 11889b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 11892999313aSBarry Smith PC contexts as well. 11909b94acceSBarry Smith 119136851e7fSLois Curfman McInnes Level: beginner 119236851e7fSLois Curfman McInnes 119394b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 11949b94acceSBarry Smith 11952999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 11969b94acceSBarry Smith @*/ 11977087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 11989b94acceSBarry Smith { 11991cee3971SBarry Smith PetscErrorCode ierr; 12001cee3971SBarry Smith 12013a40ed3dSBarry Smith PetscFunctionBegin; 12020700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12034482741eSBarry Smith PetscValidPointer(ksp,2); 12041cee3971SBarry Smith 12051cee3971SBarry Smith if (!snes->ksp) { 12061cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 12071cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 12081cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 12091cee3971SBarry Smith } 121094b7f48cSBarry Smith *ksp = snes->ksp; 12113a40ed3dSBarry Smith PetscFunctionReturn(0); 12129b94acceSBarry Smith } 121382bf6240SBarry Smith 12144a2ae208SSatish Balay #undef __FUNCT__ 12152999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 12162999313aSBarry Smith /*@ 12172999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 12182999313aSBarry Smith 12192999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 12202999313aSBarry Smith 12212999313aSBarry Smith Input Parameters: 12222999313aSBarry Smith + snes - the SNES context 12232999313aSBarry Smith - ksp - the KSP context 12242999313aSBarry Smith 12252999313aSBarry Smith Notes: 12262999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 12272999313aSBarry Smith so this routine is rarely needed. 12282999313aSBarry Smith 12292999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 12302999313aSBarry Smith decreased by one. 12312999313aSBarry Smith 12322999313aSBarry Smith Level: developer 12332999313aSBarry Smith 12342999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 12352999313aSBarry Smith 12362999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 12372999313aSBarry Smith @*/ 12387087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 12392999313aSBarry Smith { 12402999313aSBarry Smith PetscErrorCode ierr; 12412999313aSBarry Smith 12422999313aSBarry Smith PetscFunctionBegin; 12430700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12440700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 12452999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 12467dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1247906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 12482999313aSBarry Smith snes->ksp = ksp; 12492999313aSBarry Smith PetscFunctionReturn(0); 12502999313aSBarry Smith } 12512999313aSBarry Smith 12527adad957SLisandro Dalcin #if 0 12532999313aSBarry Smith #undef __FUNCT__ 12544a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 12556849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1256e24b481bSBarry Smith { 1257e24b481bSBarry Smith PetscFunctionBegin; 1258e24b481bSBarry Smith PetscFunctionReturn(0); 1259e24b481bSBarry Smith } 12607adad957SLisandro Dalcin #endif 1261e24b481bSBarry Smith 12629b94acceSBarry Smith /* -----------------------------------------------------------*/ 12634a2ae208SSatish Balay #undef __FUNCT__ 12644a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 126552baeb72SSatish Balay /*@ 12669b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 12679b94acceSBarry Smith 1268c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1269c7afd0dbSLois Curfman McInnes 1270c7afd0dbSLois Curfman McInnes Input Parameters: 1271906ed7ccSBarry Smith . comm - MPI communicator 12729b94acceSBarry Smith 12739b94acceSBarry Smith Output Parameter: 12749b94acceSBarry Smith . outsnes - the new SNES context 12759b94acceSBarry Smith 1276c7afd0dbSLois Curfman McInnes Options Database Keys: 1277c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1278c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1279c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1280c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1281c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1282c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1283c1f60f51SBarry Smith 128436851e7fSLois Curfman McInnes Level: beginner 128536851e7fSLois Curfman McInnes 12869b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 12879b94acceSBarry Smith 1288a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1289a8054027SBarry Smith 12909b94acceSBarry Smith @*/ 12917087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 12929b94acceSBarry Smith { 1293dfbe8321SBarry Smith PetscErrorCode ierr; 12949b94acceSBarry Smith SNES snes; 1295fa9f3622SBarry Smith SNESKSPEW *kctx; 129637fcc0dbSBarry Smith 12973a40ed3dSBarry Smith PetscFunctionBegin; 1298ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 12998ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 13008ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 13018ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 13028ba1e511SMatthew Knepley #endif 13038ba1e511SMatthew Knepley 13043194b578SJed Brown ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 13057adad957SLisandro Dalcin 130685385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 13072c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 130888976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 13099b94acceSBarry Smith snes->max_its = 50; 13109750a799SBarry Smith snes->max_funcs = 10000; 13119b94acceSBarry Smith snes->norm = 0.0; 1312*534ebe21SPeter Brune snes->normtype = SNES_NORM_DEFAULT; 1313b4874afaSBarry Smith snes->rtol = 1.e-8; 1314b4874afaSBarry Smith snes->ttol = 0.0; 131570441072SBarry Smith snes->abstol = 1.e-50; 1316c60f73f4SPeter Brune snes->stol = 1.e-8; 13174b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 13189b94acceSBarry Smith snes->nfuncs = 0; 131950ffb88aSMatthew Knepley snes->numFailures = 0; 132050ffb88aSMatthew Knepley snes->maxFailures = 1; 13217a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1322e35cf81dSBarry Smith snes->lagjacobian = 1; 1323a8054027SBarry Smith snes->lagpreconditioner = 1; 1324639f9d9dSBarry Smith snes->numbermonitors = 0; 13259b94acceSBarry Smith snes->data = 0; 13264dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1327186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 13286f24a144SLois Curfman McInnes snes->nwork = 0; 132958c9b817SLisandro Dalcin snes->work = 0; 133058c9b817SLisandro Dalcin snes->nvwork = 0; 133158c9b817SLisandro Dalcin snes->vwork = 0; 1332758f92a0SBarry Smith snes->conv_hist_len = 0; 1333758f92a0SBarry Smith snes->conv_hist_max = 0; 1334758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1335758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1336758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1337e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1338e4ed7901SPeter Brune snes->norm_init = 0.; 1339e4ed7901SPeter Brune snes->norm_init_set = PETSC_FALSE; 1340184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 134189b92e6fSPeter Brune snes->gssweeps = 1; 13429b94acceSBarry Smith 13433d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 13443d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 13453d4c4710SBarry Smith 13469b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 134738f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 13489b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 13499b94acceSBarry Smith kctx->version = 2; 13509b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 13519b94acceSBarry Smith this was too large for some test cases */ 135275567043SBarry Smith kctx->rtol_last = 0.0; 13539b94acceSBarry Smith kctx->rtol_max = .9; 13549b94acceSBarry Smith kctx->gamma = 1.0; 135562d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 135671f87433Sdalcinl kctx->alpha2 = kctx->alpha; 13579b94acceSBarry Smith kctx->threshold = .1; 135875567043SBarry Smith kctx->lresid_last = 0.0; 135975567043SBarry Smith kctx->norm_last = 0.0; 13609b94acceSBarry Smith 13619b94acceSBarry Smith *outsnes = snes; 13623a40ed3dSBarry Smith PetscFunctionReturn(0); 13639b94acceSBarry Smith } 13649b94acceSBarry Smith 13654a2ae208SSatish Balay #undef __FUNCT__ 13664a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 13679b94acceSBarry Smith /*@C 13689b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 13699b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 13709b94acceSBarry Smith equations. 13719b94acceSBarry Smith 13723f9fe445SBarry Smith Logically Collective on SNES 1373fee21e36SBarry Smith 1374c7afd0dbSLois Curfman McInnes Input Parameters: 1375c7afd0dbSLois Curfman McInnes + snes - the SNES context 1376c7afd0dbSLois Curfman McInnes . r - vector to store function value 1377de044059SHong Zhang . func - function evaluation routine 1378c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1379c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 13809b94acceSBarry Smith 1381c7afd0dbSLois Curfman McInnes Calling sequence of func: 13828d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1383c7afd0dbSLois Curfman McInnes 1384c586c404SJed Brown + snes - the SNES context 1385c586c404SJed Brown . x - state at which to evaluate residual 1386c586c404SJed Brown . f - vector to put residual 1387c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 13889b94acceSBarry Smith 13899b94acceSBarry Smith Notes: 13909b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 13919b94acceSBarry Smith $ f'(x) x = -f(x), 1392c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 13939b94acceSBarry Smith 139436851e7fSLois Curfman McInnes Level: beginner 139536851e7fSLois Curfman McInnes 13969b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 13979b94acceSBarry Smith 13988b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard() 13999b94acceSBarry Smith @*/ 14007087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 14019b94acceSBarry Smith { 140285385478SLisandro Dalcin PetscErrorCode ierr; 14036cab3a1bSJed Brown DM dm; 14046cab3a1bSJed Brown 14053a40ed3dSBarry Smith PetscFunctionBegin; 14060700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1407d2a683ecSLisandro Dalcin if (r) { 1408d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1409d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 141085385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 14116bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 141285385478SLisandro Dalcin snes->vec_func = r; 1413d2a683ecSLisandro Dalcin } 14146cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 14156cab3a1bSJed Brown ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr); 14163a40ed3dSBarry Smith PetscFunctionReturn(0); 14179b94acceSBarry Smith } 14189b94acceSBarry Smith 1419646217ecSPeter Brune 1420646217ecSPeter Brune #undef __FUNCT__ 1421e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction" 1422e4ed7901SPeter Brune /*@C 1423e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1424e4ed7901SPeter Brune function norm at the initialization of the method. In some 1425e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1426e4ed7901SPeter Brune SNESSolve. This function allows one to avoid a redundant call 1427e4ed7901SPeter Brune to SNESComputeFunction in that case. 1428e4ed7901SPeter Brune 1429e4ed7901SPeter Brune Logically Collective on SNES 1430e4ed7901SPeter Brune 1431e4ed7901SPeter Brune Input Parameters: 1432e4ed7901SPeter Brune + snes - the SNES context 1433e4ed7901SPeter Brune - f - vector to store function value 1434e4ed7901SPeter Brune 1435e4ed7901SPeter Brune Notes: 1436e4ed7901SPeter Brune This should not be modified during the solution procedure. 1437e4ed7901SPeter Brune 1438e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1439e4ed7901SPeter Brune 1440e4ed7901SPeter Brune Level: developer 1441e4ed7901SPeter Brune 1442e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function 1443e4ed7901SPeter Brune 1444e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm() 1445e4ed7901SPeter Brune @*/ 1446e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1447e4ed7901SPeter Brune { 1448e4ed7901SPeter Brune PetscErrorCode ierr; 1449e4ed7901SPeter Brune Vec vec_func; 1450e4ed7901SPeter Brune 1451e4ed7901SPeter Brune PetscFunctionBegin; 1452e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1453e4ed7901SPeter Brune PetscValidHeaderSpecific(f,VEC_CLASSID,2); 1454e4ed7901SPeter Brune PetscCheckSameComm(snes,1,f,2); 1455e4ed7901SPeter Brune ierr = PetscObjectReference((PetscObject)f);CHKERRQ(ierr); 1456e4ed7901SPeter Brune ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1457e4ed7901SPeter Brune ierr = VecCopy(f, vec_func);CHKERRQ(ierr); 1458217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 1459e4ed7901SPeter Brune PetscFunctionReturn(0); 1460e4ed7901SPeter Brune } 1461e4ed7901SPeter Brune 1462e4ed7901SPeter Brune 1463e4ed7901SPeter Brune #undef __FUNCT__ 1464e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm" 1465e4ed7901SPeter Brune /*@C 1466e4ed7901SPeter Brune SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm 1467e4ed7901SPeter Brune at the initialization of the method. In some instances, the user has precomputed 1468e4ed7901SPeter Brune the function and its norm before calling SNESSolve. This function allows one to 1469e4ed7901SPeter Brune avoid a redundant call to SNESComputeFunction() and VecNorm() in that case. 1470e4ed7901SPeter Brune 1471e4ed7901SPeter Brune Logically Collective on SNES 1472e4ed7901SPeter Brune 1473e4ed7901SPeter Brune Input Parameters: 1474e4ed7901SPeter Brune + snes - the SNES context 1475e4ed7901SPeter Brune - fnorm - the norm of F as set by SNESSetInitialFunction() 1476e4ed7901SPeter Brune 1477e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1478e4ed7901SPeter Brune 1479e4ed7901SPeter Brune Level: developer 1480e4ed7901SPeter Brune 1481e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm 1482e4ed7901SPeter Brune 1483e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction() 1484e4ed7901SPeter Brune @*/ 1485e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm) 1486e4ed7901SPeter Brune { 1487e4ed7901SPeter Brune PetscFunctionBegin; 1488e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1489e4ed7901SPeter Brune snes->norm_init = fnorm; 1490e4ed7901SPeter Brune snes->norm_init_set = PETSC_TRUE; 1491e4ed7901SPeter Brune PetscFunctionReturn(0); 1492e4ed7901SPeter Brune } 1493e4ed7901SPeter Brune 1494e4ed7901SPeter Brune #undef __FUNCT__ 1495*534ebe21SPeter Brune #define __FUNCT__ "SNESSetNormType" 1496*534ebe21SPeter Brune /*@ 1497*534ebe21SPeter Brune SNESSetNormType - Sets the SNESNormType used in covergence and monitoring 1498*534ebe21SPeter Brune of the SNES method. 1499*534ebe21SPeter Brune 1500*534ebe21SPeter Brune Logically Collective on SNES 1501*534ebe21SPeter Brune 1502*534ebe21SPeter Brune Input Parameters: 1503*534ebe21SPeter Brune + snes - the SNES context 1504*534ebe21SPeter Brune - normtype - the type of the norm used 1505*534ebe21SPeter Brune 1506*534ebe21SPeter Brune Notes: 1507*534ebe21SPeter Brune Only certain SNES methods support certain SNESNormTypes. Most require evaluation 1508*534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1509*534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1510*534ebe21SPeter Brune (SNESGS) and the like do not require the norm of the function to be computed, and therfore 1511*534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1512*534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1513*534ebe21SPeter Brune their solution. 1514*534ebe21SPeter Brune 1515*534ebe21SPeter Brune Level: developer 1516*534ebe21SPeter Brune 1517*534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1518*534ebe21SPeter Brune 1519*534ebe21SPeter Brune .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType 1520*534ebe21SPeter Brune @*/ 1521*534ebe21SPeter Brune PetscErrorCode SNESSetNormType(SNES snes, SNESNormType normtype) 1522*534ebe21SPeter Brune { 1523*534ebe21SPeter Brune PetscFunctionBegin; 1524*534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1525*534ebe21SPeter Brune snes->normtype = normtype; 1526*534ebe21SPeter Brune PetscFunctionReturn(0); 1527*534ebe21SPeter Brune } 1528*534ebe21SPeter Brune 1529*534ebe21SPeter Brune 1530*534ebe21SPeter Brune #undef __FUNCT__ 1531*534ebe21SPeter Brune #define __FUNCT__ "SNESGetNormType" 1532*534ebe21SPeter Brune /*@ 1533*534ebe21SPeter Brune SNESGetNormType - Gets the SNESNormType used in covergence and monitoring 1534*534ebe21SPeter Brune of the SNES method. 1535*534ebe21SPeter Brune 1536*534ebe21SPeter Brune Logically Collective on SNES 1537*534ebe21SPeter Brune 1538*534ebe21SPeter Brune Input Parameters: 1539*534ebe21SPeter Brune + snes - the SNES context 1540*534ebe21SPeter Brune - normtype - the type of the norm used 1541*534ebe21SPeter Brune 1542*534ebe21SPeter Brune Level: advanced 1543*534ebe21SPeter Brune 1544*534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1545*534ebe21SPeter Brune 1546*534ebe21SPeter Brune .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType 1547*534ebe21SPeter Brune @*/ 1548*534ebe21SPeter Brune PetscErrorCode SNESGetNormType(SNES snes, SNESNormType *normtype) 1549*534ebe21SPeter Brune { 1550*534ebe21SPeter Brune PetscFunctionBegin; 1551*534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1552*534ebe21SPeter Brune *normtype = snes->normtype; 1553*534ebe21SPeter Brune PetscFunctionReturn(0); 1554*534ebe21SPeter Brune } 1555*534ebe21SPeter Brune 1556*534ebe21SPeter Brune #undef __FUNCT__ 1557646217ecSPeter Brune #define __FUNCT__ "SNESSetGS" 1558c79ef259SPeter Brune /*@C 1559c79ef259SPeter Brune SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for 1560c79ef259SPeter Brune use with composed nonlinear solvers. 1561c79ef259SPeter Brune 1562c79ef259SPeter Brune Input Parameters: 1563c79ef259SPeter Brune + snes - the SNES context 1564c79ef259SPeter Brune . gsfunc - function evaluation routine 1565c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 1566c79ef259SPeter Brune smoother evaluation routine (may be PETSC_NULL) 1567c79ef259SPeter Brune 1568c79ef259SPeter Brune Calling sequence of func: 1569c79ef259SPeter Brune $ func (SNES snes,Vec x,Vec b,void *ctx); 1570c79ef259SPeter Brune 1571c79ef259SPeter Brune + X - solution vector 1572c79ef259SPeter Brune . B - RHS vector 1573d28543b3SPeter Brune - ctx - optional user-defined Gauss-Seidel context 1574c79ef259SPeter Brune 1575c79ef259SPeter Brune Notes: 1576c79ef259SPeter Brune The GS routines are used by the composed nonlinear solver to generate 1577c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1578c79ef259SPeter Brune 1579d28543b3SPeter Brune Level: intermediate 1580c79ef259SPeter Brune 1581d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1582c79ef259SPeter Brune 1583c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS() 1584c79ef259SPeter Brune @*/ 15856cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx) 15866cab3a1bSJed Brown { 15876cab3a1bSJed Brown PetscErrorCode ierr; 15886cab3a1bSJed Brown DM dm; 15896cab3a1bSJed Brown 1590646217ecSPeter Brune PetscFunctionBegin; 15916cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15926cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 15936cab3a1bSJed Brown ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr); 1594646217ecSPeter Brune PetscFunctionReturn(0); 1595646217ecSPeter Brune } 1596646217ecSPeter Brune 1597d25893d9SBarry Smith #undef __FUNCT__ 159889b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps" 159989b92e6fSPeter Brune /*@ 160089b92e6fSPeter Brune SNESSetGSSweeps - Sets the number of sweeps of GS to use. 160189b92e6fSPeter Brune 160289b92e6fSPeter Brune Input Parameters: 160389b92e6fSPeter Brune + snes - the SNES context 160489b92e6fSPeter Brune - sweeps - the number of sweeps of GS to perform. 160589b92e6fSPeter Brune 160689b92e6fSPeter Brune Level: intermediate 160789b92e6fSPeter Brune 160889b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 160989b92e6fSPeter Brune 161089b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps() 161189b92e6fSPeter Brune @*/ 161289b92e6fSPeter Brune 161389b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) { 161489b92e6fSPeter Brune PetscFunctionBegin; 161589b92e6fSPeter Brune snes->gssweeps = sweeps; 161689b92e6fSPeter Brune PetscFunctionReturn(0); 161789b92e6fSPeter Brune } 161889b92e6fSPeter Brune 161989b92e6fSPeter Brune 162089b92e6fSPeter Brune #undef __FUNCT__ 162189b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps" 162289b92e6fSPeter Brune /*@ 162389b92e6fSPeter Brune SNESGetGSSweeps - Gets the number of sweeps GS will use. 162489b92e6fSPeter Brune 162589b92e6fSPeter Brune Input Parameters: 162689b92e6fSPeter Brune . snes - the SNES context 162789b92e6fSPeter Brune 162889b92e6fSPeter Brune Output Parameters: 162989b92e6fSPeter Brune . sweeps - the number of sweeps of GS to perform. 163089b92e6fSPeter Brune 163189b92e6fSPeter Brune Level: intermediate 163289b92e6fSPeter Brune 163389b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 163489b92e6fSPeter Brune 163589b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps() 163689b92e6fSPeter Brune @*/ 163789b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) { 163889b92e6fSPeter Brune PetscFunctionBegin; 163989b92e6fSPeter Brune *sweeps = snes->gssweeps; 164089b92e6fSPeter Brune PetscFunctionReturn(0); 164189b92e6fSPeter Brune } 164289b92e6fSPeter Brune 164389b92e6fSPeter Brune #undef __FUNCT__ 16448b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 16458b0a5094SBarry Smith PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 16468b0a5094SBarry Smith { 16478b0a5094SBarry Smith PetscErrorCode ierr; 16486cab3a1bSJed Brown void *functx,*jacctx; 16496cab3a1bSJed Brown 16508b0a5094SBarry Smith PetscFunctionBegin; 16516cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 16526cab3a1bSJed Brown ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr); 16538b0a5094SBarry Smith /* A(x)*x - b(x) */ 16546cab3a1bSJed Brown ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr); 16556cab3a1bSJed Brown ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr); 16568b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 16578b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 16588b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 16598b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 16608b0a5094SBarry Smith PetscFunctionReturn(0); 16618b0a5094SBarry Smith } 16628b0a5094SBarry Smith 16638b0a5094SBarry Smith #undef __FUNCT__ 16648b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 16658b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 16668b0a5094SBarry Smith { 16678b0a5094SBarry Smith PetscFunctionBegin; 16688b0a5094SBarry Smith *flag = snes->matstruct; 16698b0a5094SBarry Smith PetscFunctionReturn(0); 16708b0a5094SBarry Smith } 16718b0a5094SBarry Smith 16728b0a5094SBarry Smith #undef __FUNCT__ 16738b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 16748b0a5094SBarry Smith /*@C 16750d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 16768b0a5094SBarry Smith 16778b0a5094SBarry Smith Logically Collective on SNES 16788b0a5094SBarry Smith 16798b0a5094SBarry Smith Input Parameters: 16808b0a5094SBarry Smith + snes - the SNES context 16818b0a5094SBarry Smith . r - vector to store function value 16828b0a5094SBarry Smith . func - function evaluation routine 16838b0a5094SBarry 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) 16848b0a5094SBarry Smith . mat - matrix to store A 16858b0a5094SBarry Smith . mfunc - function to compute matrix value 16868b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 16878b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 16888b0a5094SBarry Smith 16898b0a5094SBarry Smith Calling sequence of func: 16908b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 16918b0a5094SBarry Smith 16928b0a5094SBarry Smith + f - function vector 16938b0a5094SBarry Smith - ctx - optional user-defined function context 16948b0a5094SBarry Smith 16958b0a5094SBarry Smith Calling sequence of mfunc: 16968b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 16978b0a5094SBarry Smith 16988b0a5094SBarry Smith + x - input vector 16998b0a5094SBarry 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(), 17008b0a5094SBarry Smith normally just pass mat in this location 17018b0a5094SBarry Smith . mat - form A(x) matrix 17028b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 17038b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 17048b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 17058b0a5094SBarry Smith 17068b0a5094SBarry Smith Notes: 17078b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 17088b0a5094SBarry Smith 17098b0a5094SBarry 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} 17108b0a5094SBarry 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. 17118b0a5094SBarry Smith 17128b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 17138b0a5094SBarry Smith 17140d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 17150d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 17168b0a5094SBarry Smith 17178b0a5094SBarry 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 17188b0a5094SBarry 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 17198b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 17208b0a5094SBarry Smith 17218b0a5094SBarry Smith Level: beginner 17228b0a5094SBarry Smith 17238b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 17248b0a5094SBarry Smith 17250d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard() 17268b0a5094SBarry Smith @*/ 17278b0a5094SBarry 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) 17288b0a5094SBarry Smith { 17298b0a5094SBarry Smith PetscErrorCode ierr; 17308b0a5094SBarry Smith PetscFunctionBegin; 17318b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 17328b0a5094SBarry Smith snes->ops->computepfunction = func; 17338b0a5094SBarry Smith snes->ops->computepjacobian = mfunc; 17348b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 17358b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 17368b0a5094SBarry Smith PetscFunctionReturn(0); 17378b0a5094SBarry Smith } 17388b0a5094SBarry Smith 17398b0a5094SBarry Smith #undef __FUNCT__ 1740d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1741d25893d9SBarry Smith /*@C 1742d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1743d25893d9SBarry Smith 1744d25893d9SBarry Smith Logically Collective on SNES 1745d25893d9SBarry Smith 1746d25893d9SBarry Smith Input Parameters: 1747d25893d9SBarry Smith + snes - the SNES context 1748d25893d9SBarry Smith . func - function evaluation routine 1749d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1750d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1751d25893d9SBarry Smith 1752d25893d9SBarry Smith Calling sequence of func: 1753d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1754d25893d9SBarry Smith 1755d25893d9SBarry Smith . f - function vector 1756d25893d9SBarry Smith - ctx - optional user-defined function context 1757d25893d9SBarry Smith 1758d25893d9SBarry Smith Level: intermediate 1759d25893d9SBarry Smith 1760d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1761d25893d9SBarry Smith 1762d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1763d25893d9SBarry Smith @*/ 1764d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1765d25893d9SBarry Smith { 1766d25893d9SBarry Smith PetscFunctionBegin; 1767d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1768d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1769d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1770d25893d9SBarry Smith PetscFunctionReturn(0); 1771d25893d9SBarry Smith } 1772d25893d9SBarry Smith 17733ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 17743ab0aad5SBarry Smith #undef __FUNCT__ 17751096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 17761096aae1SMatthew Knepley /*@C 17771096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 17781096aae1SMatthew Knepley it assumes a zero right hand side. 17791096aae1SMatthew Knepley 17803f9fe445SBarry Smith Logically Collective on SNES 17811096aae1SMatthew Knepley 17821096aae1SMatthew Knepley Input Parameter: 17831096aae1SMatthew Knepley . snes - the SNES context 17841096aae1SMatthew Knepley 17851096aae1SMatthew Knepley Output Parameter: 1786bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 17871096aae1SMatthew Knepley 17881096aae1SMatthew Knepley Level: intermediate 17891096aae1SMatthew Knepley 17901096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 17911096aae1SMatthew Knepley 179285385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 17931096aae1SMatthew Knepley @*/ 17947087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 17951096aae1SMatthew Knepley { 17961096aae1SMatthew Knepley PetscFunctionBegin; 17970700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 17981096aae1SMatthew Knepley PetscValidPointer(rhs,2); 179985385478SLisandro Dalcin *rhs = snes->vec_rhs; 18001096aae1SMatthew Knepley PetscFunctionReturn(0); 18011096aae1SMatthew Knepley } 18021096aae1SMatthew Knepley 18031096aae1SMatthew Knepley #undef __FUNCT__ 18044a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 18059b94acceSBarry Smith /*@ 180636851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 18079b94acceSBarry Smith SNESSetFunction(). 18089b94acceSBarry Smith 1809c7afd0dbSLois Curfman McInnes Collective on SNES 1810c7afd0dbSLois Curfman McInnes 18119b94acceSBarry Smith Input Parameters: 1812c7afd0dbSLois Curfman McInnes + snes - the SNES context 1813c7afd0dbSLois Curfman McInnes - x - input vector 18149b94acceSBarry Smith 18159b94acceSBarry Smith Output Parameter: 18163638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 18179b94acceSBarry Smith 18181bffabb2SLois Curfman McInnes Notes: 181936851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 182036851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 182136851e7fSLois Curfman McInnes themselves. 182236851e7fSLois Curfman McInnes 182336851e7fSLois Curfman McInnes Level: developer 182436851e7fSLois Curfman McInnes 18259b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 18269b94acceSBarry Smith 1827a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 18289b94acceSBarry Smith @*/ 18297087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 18309b94acceSBarry Smith { 1831dfbe8321SBarry Smith PetscErrorCode ierr; 18326cab3a1bSJed Brown DM dm; 18336cab3a1bSJed Brown SNESDM sdm; 18349b94acceSBarry Smith 18353a40ed3dSBarry Smith PetscFunctionBegin; 18360700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 18370700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 18380700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1839c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1840c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 18414ec14c9cSBarry Smith VecValidValues(x,2,PETSC_TRUE); 1842184914b5SBarry Smith 18436cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18446cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 1845d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 18466cab3a1bSJed Brown if (sdm->computefunction) { 1847d64ed03dSBarry Smith PetscStackPush("SNES user function"); 18486cab3a1bSJed Brown ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 1849d64ed03dSBarry Smith PetscStackPop; 185073250ac0SBarry Smith } else if (snes->dm) { 1851644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1852c90fad12SPeter Brune } else if (snes->vec_rhs) { 1853c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1854644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 185585385478SLisandro Dalcin if (snes->vec_rhs) { 185685385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 18573ab0aad5SBarry Smith } 1858ae3c334cSLois Curfman McInnes snes->nfuncs++; 1859d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 18604ec14c9cSBarry Smith VecValidValues(y,3,PETSC_FALSE); 18613a40ed3dSBarry Smith PetscFunctionReturn(0); 18629b94acceSBarry Smith } 18639b94acceSBarry Smith 18644a2ae208SSatish Balay #undef __FUNCT__ 1865646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1866c79ef259SPeter Brune /*@ 1867c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1868c79ef259SPeter Brune SNESSetGS(). 1869c79ef259SPeter Brune 1870c79ef259SPeter Brune Collective on SNES 1871c79ef259SPeter Brune 1872c79ef259SPeter Brune Input Parameters: 1873c79ef259SPeter Brune + snes - the SNES context 1874c79ef259SPeter Brune . x - input vector 1875c79ef259SPeter Brune - b - rhs vector 1876c79ef259SPeter Brune 1877c79ef259SPeter Brune Output Parameter: 1878c79ef259SPeter Brune . x - new solution vector 1879c79ef259SPeter Brune 1880c79ef259SPeter Brune Notes: 1881c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1882c79ef259SPeter Brune implementations, so most users would not generally call this routine 1883c79ef259SPeter Brune themselves. 1884c79ef259SPeter Brune 1885c79ef259SPeter Brune Level: developer 1886c79ef259SPeter Brune 1887c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1888c79ef259SPeter Brune 1889c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1890c79ef259SPeter Brune @*/ 1891646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1892646217ecSPeter Brune { 1893646217ecSPeter Brune PetscErrorCode ierr; 189489b92e6fSPeter Brune PetscInt i; 18956cab3a1bSJed Brown DM dm; 18966cab3a1bSJed Brown SNESDM sdm; 1897646217ecSPeter Brune 1898646217ecSPeter Brune PetscFunctionBegin; 1899646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1900646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1901646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1902646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 1903646217ecSPeter Brune if(b) PetscCheckSameComm(snes,1,b,3); 19044ec14c9cSBarry Smith if (b) VecValidValues(b,2,PETSC_TRUE); 1905701cf23dSPeter Brune ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 19066cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 19076cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 19086cab3a1bSJed Brown if (sdm->computegs) { 190989b92e6fSPeter Brune for (i = 0; i < snes->gssweeps; i++) { 1910646217ecSPeter Brune PetscStackPush("SNES user GS"); 19116cab3a1bSJed Brown ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 1912646217ecSPeter Brune PetscStackPop; 191389b92e6fSPeter Brune } 1914646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 1915701cf23dSPeter Brune ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 19164ec14c9cSBarry Smith VecValidValues(x,3,PETSC_FALSE); 1917646217ecSPeter Brune PetscFunctionReturn(0); 1918646217ecSPeter Brune } 1919646217ecSPeter Brune 1920646217ecSPeter Brune 1921646217ecSPeter Brune #undef __FUNCT__ 19224a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 192362fef451SLois Curfman McInnes /*@ 192462fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 192562fef451SLois Curfman McInnes set with SNESSetJacobian(). 192662fef451SLois Curfman McInnes 1927c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1928c7afd0dbSLois Curfman McInnes 192962fef451SLois Curfman McInnes Input Parameters: 1930c7afd0dbSLois Curfman McInnes + snes - the SNES context 1931c7afd0dbSLois Curfman McInnes - x - input vector 193262fef451SLois Curfman McInnes 193362fef451SLois Curfman McInnes Output Parameters: 1934c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 193562fef451SLois Curfman McInnes . B - optional preconditioning matrix 19362b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1937fee21e36SBarry Smith 1938e35cf81dSBarry Smith Options Database Keys: 1939e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1940693365a8SJed Brown . -snes_lag_jacobian <lag> 1941693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1942693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1943693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 19444c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1945c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 1946c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 1947c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 1948c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 1949c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 19504c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 1951c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 1952c01495d3SJed Brown 1953e35cf81dSBarry Smith 195462fef451SLois Curfman McInnes Notes: 195562fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 195662fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 195762fef451SLois Curfman McInnes 195894b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1959dc5a77f8SLois Curfman McInnes flag parameter. 196062fef451SLois Curfman McInnes 196136851e7fSLois Curfman McInnes Level: developer 196236851e7fSLois Curfman McInnes 196362fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 196462fef451SLois Curfman McInnes 1965e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 196662fef451SLois Curfman McInnes @*/ 19677087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 19689b94acceSBarry Smith { 1969dfbe8321SBarry Smith PetscErrorCode ierr; 1970ace3abfcSBarry Smith PetscBool flag; 19716cab3a1bSJed Brown DM dm; 19726cab3a1bSJed Brown SNESDM sdm; 19733a40ed3dSBarry Smith 19743a40ed3dSBarry Smith PetscFunctionBegin; 19750700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 19760700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 19774482741eSBarry Smith PetscValidPointer(flg,5); 1978c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 19794ec14c9cSBarry Smith VecValidValues(X,2,PETSC_TRUE); 19806cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 19816cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 19826cab3a1bSJed Brown if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 1983ebd3b9afSBarry Smith 1984ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1985ebd3b9afSBarry Smith 1986fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 1987fe3ffe1eSBarry Smith snes->lagjacobian = -1; 1988fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1989fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 1990e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1991e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1992ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1993ebd3b9afSBarry Smith if (flag) { 1994ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1995ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1996ebd3b9afSBarry Smith } 1997e35cf81dSBarry Smith PetscFunctionReturn(0); 1998e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1999e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 2000e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 2001ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 2002ebd3b9afSBarry Smith if (flag) { 2003ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2004ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2005ebd3b9afSBarry Smith } 2006e35cf81dSBarry Smith PetscFunctionReturn(0); 2007e35cf81dSBarry Smith } 2008e35cf81dSBarry Smith 2009c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 2010e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 2011d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 20126cab3a1bSJed Brown ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr); 2013d64ed03dSBarry Smith PetscStackPop; 2014d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 2015a8054027SBarry Smith 20163b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 20173b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 20183b4f5425SBarry Smith snes->lagpreconditioner = -1; 20193b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 2020a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 2021a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 2022a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 2023a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 2024a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 2025a8054027SBarry Smith } 2026a8054027SBarry Smith 20276d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 20280700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 20290700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 2030693365a8SJed Brown { 2031693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 2032693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 2033693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 2034693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 2035693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 2036693365a8SJed Brown if (flag || flag_draw || flag_contour) { 2037693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 2038693365a8SJed Brown MatStructure mstruct; 2039693365a8SJed Brown PetscViewer vdraw,vstdout; 20406b3a5b13SJed Brown PetscBool flg; 2041693365a8SJed Brown if (flag_operator) { 2042693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 2043693365a8SJed Brown Bexp = Bexp_mine; 2044693365a8SJed Brown } else { 2045693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 2046693365a8SJed Brown ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 2047693365a8SJed Brown if (flg) Bexp = *B; 2048693365a8SJed Brown else { 2049693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 2050693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 2051693365a8SJed Brown Bexp = Bexp_mine; 2052693365a8SJed Brown } 2053693365a8SJed Brown } 2054693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 2055693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 2056693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 2057693365a8SJed Brown if (flag_draw || flag_contour) { 2058693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2059693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 2060693365a8SJed Brown } else vdraw = PETSC_NULL; 2061693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 2062693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 2063693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 2064693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 2065693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2066693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 2067693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2068693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 2069693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2070693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 2071693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2072693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 2073693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2074693365a8SJed Brown } 2075693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2076693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2077693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 2078693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 2079693365a8SJed Brown } 2080693365a8SJed Brown } 20814c30e9fbSJed Brown { 20826719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 20836719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 20844c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 20856719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 20864c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 20874c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 20886719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 20896719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 20906719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 20916719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 20924c30e9fbSJed Brown Mat Bfd; 20934c30e9fbSJed Brown MatStructure mstruct; 20944c30e9fbSJed Brown PetscViewer vdraw,vstdout; 20954c30e9fbSJed Brown ISColoring iscoloring; 20964c30e9fbSJed Brown MatFDColoring matfdcoloring; 20974c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 20984c30e9fbSJed Brown void *funcctx; 20996719d8e4SJed Brown PetscReal norm1,norm2,normmax; 21004c30e9fbSJed Brown 21014c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 21024c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 21034c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 21044c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 21054c30e9fbSJed Brown 21064c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 21074c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 21084c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 21094c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 21104c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 21114c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 21124c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 21134c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 21144c30e9fbSJed Brown 21154c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 21164c30e9fbSJed Brown if (flag_draw || flag_contour) { 21174c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 21184c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 21194c30e9fbSJed Brown } else vdraw = PETSC_NULL; 21204c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 21216719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 21224c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 21234c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 21246719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 21254c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 21264c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 21274c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 21286719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 21294c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 21306719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 21316719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 21324c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 21334c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 21344c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 21354c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 21364c30e9fbSJed Brown } 21374c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 21386719d8e4SJed Brown 21396719d8e4SJed Brown if (flag_threshold) { 21406719d8e4SJed Brown PetscInt bs,rstart,rend,i; 21416719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 21426719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 21436719d8e4SJed Brown for (i=rstart; i<rend; i++) { 21446719d8e4SJed Brown const PetscScalar *ba,*ca; 21456719d8e4SJed Brown const PetscInt *bj,*cj; 21466719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 21476719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 21486719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 21496719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 21506719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 21516719d8e4SJed Brown for (j=0; j<bn; j++) { 21526719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 21536719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 21546719d8e4SJed Brown maxentrycol = bj[j]; 21556719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 21566719d8e4SJed Brown } 21576719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 21586719d8e4SJed Brown maxdiffcol = bj[j]; 21596719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 21606719d8e4SJed Brown } 21616719d8e4SJed Brown if (rdiff > maxrdiff) { 21626719d8e4SJed Brown maxrdiffcol = bj[j]; 21636719d8e4SJed Brown maxrdiff = rdiff; 21646719d8e4SJed Brown } 21656719d8e4SJed Brown } 21666719d8e4SJed Brown if (maxrdiff > 1) { 21676719d8e4SJed 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); 21686719d8e4SJed Brown for (j=0; j<bn; j++) { 21696719d8e4SJed Brown PetscReal rdiff; 21706719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 21716719d8e4SJed Brown if (rdiff > 1) { 21726719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 21736719d8e4SJed Brown } 21746719d8e4SJed Brown } 21756719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 21766719d8e4SJed Brown } 21776719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 21786719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 21796719d8e4SJed Brown } 21806719d8e4SJed Brown } 21814c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 21824c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 21834c30e9fbSJed Brown } 21844c30e9fbSJed Brown } 21853a40ed3dSBarry Smith PetscFunctionReturn(0); 21869b94acceSBarry Smith } 21879b94acceSBarry Smith 21884a2ae208SSatish Balay #undef __FUNCT__ 21894a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 21909b94acceSBarry Smith /*@C 21919b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2192044dda88SLois Curfman McInnes location to store the matrix. 21939b94acceSBarry Smith 21943f9fe445SBarry Smith Logically Collective on SNES and Mat 2195c7afd0dbSLois Curfman McInnes 21969b94acceSBarry Smith Input Parameters: 2197c7afd0dbSLois Curfman McInnes + snes - the SNES context 21989b94acceSBarry Smith . A - Jacobian matrix 21999b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 2200efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 2201c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 2202efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 22039b94acceSBarry Smith 22049b94acceSBarry Smith Calling sequence of func: 22058d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 22069b94acceSBarry Smith 2207c7afd0dbSLois Curfman McInnes + x - input vector 22089b94acceSBarry Smith . A - Jacobian matrix 22099b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 2210ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 22112b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 2212c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 22139b94acceSBarry Smith 22149b94acceSBarry Smith Notes: 221594b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 22162cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 2217ac21db08SLois Curfman McInnes 2218ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 22199b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 22209b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 22219b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 22229b94acceSBarry Smith throughout the global iterations. 22239b94acceSBarry Smith 222416913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 222516913363SBarry Smith each matrix. 222616913363SBarry Smith 2227a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 2228a8a26c1eSJed Brown must be a MatFDColoring. 2229a8a26c1eSJed Brown 2230c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2231c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2232c3cc8fd1SJed Brown 223336851e7fSLois Curfman McInnes Level: beginner 223436851e7fSLois Curfman McInnes 22359b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 22369b94acceSBarry Smith 22373ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 22389b94acceSBarry Smith @*/ 22397087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 22409b94acceSBarry Smith { 2241dfbe8321SBarry Smith PetscErrorCode ierr; 22426cab3a1bSJed Brown DM dm; 22433a7fca6bSBarry Smith 22443a40ed3dSBarry Smith PetscFunctionBegin; 22450700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 22460700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 22470700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 2248c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 224906975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 22506cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 22516cab3a1bSJed Brown ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr); 22523a7fca6bSBarry Smith if (A) { 22537dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 22546bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 22559b94acceSBarry Smith snes->jacobian = A; 22563a7fca6bSBarry Smith } 22573a7fca6bSBarry Smith if (B) { 22587dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 22596bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 22609b94acceSBarry Smith snes->jacobian_pre = B; 22613a7fca6bSBarry Smith } 22623a40ed3dSBarry Smith PetscFunctionReturn(0); 22639b94acceSBarry Smith } 226462fef451SLois Curfman McInnes 22654a2ae208SSatish Balay #undef __FUNCT__ 22664a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 2267c2aafc4cSSatish Balay /*@C 2268b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2269b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2270b4fd4287SBarry Smith 2271c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2272c7afd0dbSLois Curfman McInnes 2273b4fd4287SBarry Smith Input Parameter: 2274b4fd4287SBarry Smith . snes - the nonlinear solver context 2275b4fd4287SBarry Smith 2276b4fd4287SBarry Smith Output Parameters: 2277c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 2278b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 227970e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 228070e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 2281fee21e36SBarry Smith 228236851e7fSLois Curfman McInnes Level: advanced 228336851e7fSLois Curfman McInnes 2284b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 2285b4fd4287SBarry Smith @*/ 22867087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 2287b4fd4287SBarry Smith { 22886cab3a1bSJed Brown PetscErrorCode ierr; 22896cab3a1bSJed Brown DM dm; 22906cab3a1bSJed Brown SNESDM sdm; 22916cab3a1bSJed Brown 22923a40ed3dSBarry Smith PetscFunctionBegin; 22930700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2294b4fd4287SBarry Smith if (A) *A = snes->jacobian; 2295b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 22966cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 22976cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 22986cab3a1bSJed Brown if (func) *func = sdm->computejacobian; 22996cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 23003a40ed3dSBarry Smith PetscFunctionReturn(0); 2301b4fd4287SBarry Smith } 2302b4fd4287SBarry Smith 23039b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 23049b94acceSBarry Smith 23054a2ae208SSatish Balay #undef __FUNCT__ 23064a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 23079b94acceSBarry Smith /*@ 23089b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2309272ac6f2SLois Curfman McInnes of a nonlinear solver. 23109b94acceSBarry Smith 2311fee21e36SBarry Smith Collective on SNES 2312fee21e36SBarry Smith 2313c7afd0dbSLois Curfman McInnes Input Parameters: 231470e92668SMatthew Knepley . snes - the SNES context 2315c7afd0dbSLois Curfman McInnes 2316272ac6f2SLois Curfman McInnes Notes: 2317272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2318272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2319272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2320272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2321272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2322272ac6f2SLois Curfman McInnes 232336851e7fSLois Curfman McInnes Level: advanced 232436851e7fSLois Curfman McInnes 23259b94acceSBarry Smith .keywords: SNES, nonlinear, setup 23269b94acceSBarry Smith 23279b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 23289b94acceSBarry Smith @*/ 23297087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 23309b94acceSBarry Smith { 2331dfbe8321SBarry Smith PetscErrorCode ierr; 23326cab3a1bSJed Brown DM dm; 23336cab3a1bSJed Brown SNESDM sdm; 23343a40ed3dSBarry Smith 23353a40ed3dSBarry Smith PetscFunctionBegin; 23360700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23374dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 23389b94acceSBarry Smith 23397adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 234085385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 234185385478SLisandro Dalcin } 234285385478SLisandro Dalcin 2343a63bb30eSJed Brown ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 234417186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 234558c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 234658c9b817SLisandro Dalcin 234758c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 234858c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 234958c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 235058c9b817SLisandro Dalcin } 235158c9b817SLisandro Dalcin 23526cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 23536cab3a1bSJed Brown ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */ 23546cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 23556cab3a1bSJed Brown if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc"); 23566cab3a1bSJed Brown if (!snes->vec_func) { 23576cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2358214df951SJed Brown } 2359efd51863SBarry Smith 2360b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 2361b710008aSBarry Smith 2362f1c6b773SPeter Brune if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);} 23639e764e56SPeter Brune 2364d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 2365d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2366d25893d9SBarry Smith } 2367d25893d9SBarry Smith 2368410397dcSLisandro Dalcin if (snes->ops->setup) { 2369410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2370410397dcSLisandro Dalcin } 237158c9b817SLisandro Dalcin 23727aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 23733a40ed3dSBarry Smith PetscFunctionReturn(0); 23749b94acceSBarry Smith } 23759b94acceSBarry Smith 23764a2ae208SSatish Balay #undef __FUNCT__ 237737596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 237837596af1SLisandro Dalcin /*@ 237937596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 238037596af1SLisandro Dalcin 238137596af1SLisandro Dalcin Collective on SNES 238237596af1SLisandro Dalcin 238337596af1SLisandro Dalcin Input Parameter: 238437596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 238537596af1SLisandro Dalcin 2386d25893d9SBarry Smith Level: intermediate 2387d25893d9SBarry Smith 2388d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 238937596af1SLisandro Dalcin 239037596af1SLisandro Dalcin .keywords: SNES, destroy 239137596af1SLisandro Dalcin 239237596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 239337596af1SLisandro Dalcin @*/ 239437596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 239537596af1SLisandro Dalcin { 239637596af1SLisandro Dalcin PetscErrorCode ierr; 239737596af1SLisandro Dalcin 239837596af1SLisandro Dalcin PetscFunctionBegin; 239937596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2400d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2401d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2402d25893d9SBarry Smith snes->user = PETSC_NULL; 2403d25893d9SBarry Smith } 24048a23116dSBarry Smith if (snes->pc) { 24058a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 24068a23116dSBarry Smith } 24078a23116dSBarry Smith 240837596af1SLisandro Dalcin if (snes->ops->reset) { 240937596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 241037596af1SLisandro Dalcin } 24119e764e56SPeter Brune if (snes->ksp) { 24129e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 24139e764e56SPeter Brune } 24149e764e56SPeter Brune 24159e764e56SPeter Brune if (snes->linesearch) { 2416f1c6b773SPeter Brune ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 24179e764e56SPeter Brune } 24189e764e56SPeter Brune 24196bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 24206bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 24216bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 24226bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 24236bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 24246bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2425c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2426c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 242737596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 242837596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 242937596af1SLisandro Dalcin PetscFunctionReturn(0); 243037596af1SLisandro Dalcin } 243137596af1SLisandro Dalcin 243237596af1SLisandro Dalcin #undef __FUNCT__ 24334a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 243452baeb72SSatish Balay /*@ 24359b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 24369b94acceSBarry Smith with SNESCreate(). 24379b94acceSBarry Smith 2438c7afd0dbSLois Curfman McInnes Collective on SNES 2439c7afd0dbSLois Curfman McInnes 24409b94acceSBarry Smith Input Parameter: 24419b94acceSBarry Smith . snes - the SNES context 24429b94acceSBarry Smith 244336851e7fSLois Curfman McInnes Level: beginner 244436851e7fSLois Curfman McInnes 24459b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 24469b94acceSBarry Smith 244763a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 24489b94acceSBarry Smith @*/ 24496bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 24509b94acceSBarry Smith { 24516849ba73SBarry Smith PetscErrorCode ierr; 24523a40ed3dSBarry Smith 24533a40ed3dSBarry Smith PetscFunctionBegin; 24546bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 24556bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 24566bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2457d4bb536fSBarry Smith 24586bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 24598a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 24606b8b9a38SLisandro Dalcin 2461be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 24626bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 24636bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 24646d4c513bSLisandro Dalcin 24656bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 24666bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 2467f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 24686b8b9a38SLisandro Dalcin 24696bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 24706bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 24716bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 24726b8b9a38SLisandro Dalcin } 24736bf464f9SBarry Smith if ((*snes)->conv_malloc) { 24746bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 24756bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 247658c9b817SLisandro Dalcin } 24776bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2478a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 24793a40ed3dSBarry Smith PetscFunctionReturn(0); 24809b94acceSBarry Smith } 24819b94acceSBarry Smith 24829b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 24839b94acceSBarry Smith 24844a2ae208SSatish Balay #undef __FUNCT__ 2485a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2486a8054027SBarry Smith /*@ 2487a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2488a8054027SBarry Smith 24893f9fe445SBarry Smith Logically Collective on SNES 2490a8054027SBarry Smith 2491a8054027SBarry Smith Input Parameters: 2492a8054027SBarry Smith + snes - the SNES context 2493a8054027SBarry 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 24943b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2495a8054027SBarry Smith 2496a8054027SBarry Smith Options Database Keys: 2497a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2498a8054027SBarry Smith 2499a8054027SBarry Smith Notes: 2500a8054027SBarry Smith The default is 1 2501a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2502a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2503a8054027SBarry Smith 2504a8054027SBarry Smith Level: intermediate 2505a8054027SBarry Smith 2506a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2507a8054027SBarry Smith 2508e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2509a8054027SBarry Smith 2510a8054027SBarry Smith @*/ 25117087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2512a8054027SBarry Smith { 2513a8054027SBarry Smith PetscFunctionBegin; 25140700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2515e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2516e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2517c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2518a8054027SBarry Smith snes->lagpreconditioner = lag; 2519a8054027SBarry Smith PetscFunctionReturn(0); 2520a8054027SBarry Smith } 2521a8054027SBarry Smith 2522a8054027SBarry Smith #undef __FUNCT__ 2523efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2524efd51863SBarry Smith /*@ 2525efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2526efd51863SBarry Smith 2527efd51863SBarry Smith Logically Collective on SNES 2528efd51863SBarry Smith 2529efd51863SBarry Smith Input Parameters: 2530efd51863SBarry Smith + snes - the SNES context 2531efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2532efd51863SBarry Smith 2533efd51863SBarry Smith Options Database Keys: 2534efd51863SBarry Smith . -snes_grid_sequence <steps> 2535efd51863SBarry Smith 2536efd51863SBarry Smith Level: intermediate 2537efd51863SBarry Smith 2538c0df2a02SJed Brown Notes: 2539c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2540c0df2a02SJed Brown 2541efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2542efd51863SBarry Smith 2543efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2544efd51863SBarry Smith 2545efd51863SBarry Smith @*/ 2546efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2547efd51863SBarry Smith { 2548efd51863SBarry Smith PetscFunctionBegin; 2549efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2550efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2551efd51863SBarry Smith snes->gridsequence = steps; 2552efd51863SBarry Smith PetscFunctionReturn(0); 2553efd51863SBarry Smith } 2554efd51863SBarry Smith 2555efd51863SBarry Smith #undef __FUNCT__ 2556a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2557a8054027SBarry Smith /*@ 2558a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2559a8054027SBarry Smith 25603f9fe445SBarry Smith Not Collective 2561a8054027SBarry Smith 2562a8054027SBarry Smith Input Parameter: 2563a8054027SBarry Smith . snes - the SNES context 2564a8054027SBarry Smith 2565a8054027SBarry Smith Output Parameter: 2566a8054027SBarry 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 25673b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2568a8054027SBarry Smith 2569a8054027SBarry Smith Options Database Keys: 2570a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2571a8054027SBarry Smith 2572a8054027SBarry Smith Notes: 2573a8054027SBarry Smith The default is 1 2574a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2575a8054027SBarry Smith 2576a8054027SBarry Smith Level: intermediate 2577a8054027SBarry Smith 2578a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2579a8054027SBarry Smith 2580a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2581a8054027SBarry Smith 2582a8054027SBarry Smith @*/ 25837087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2584a8054027SBarry Smith { 2585a8054027SBarry Smith PetscFunctionBegin; 25860700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2587a8054027SBarry Smith *lag = snes->lagpreconditioner; 2588a8054027SBarry Smith PetscFunctionReturn(0); 2589a8054027SBarry Smith } 2590a8054027SBarry Smith 2591a8054027SBarry Smith #undef __FUNCT__ 2592e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2593e35cf81dSBarry Smith /*@ 2594e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2595e35cf81dSBarry Smith often the preconditioner is rebuilt. 2596e35cf81dSBarry Smith 25973f9fe445SBarry Smith Logically Collective on SNES 2598e35cf81dSBarry Smith 2599e35cf81dSBarry Smith Input Parameters: 2600e35cf81dSBarry Smith + snes - the SNES context 2601e35cf81dSBarry 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 2602fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2603e35cf81dSBarry Smith 2604e35cf81dSBarry Smith Options Database Keys: 2605e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2606e35cf81dSBarry Smith 2607e35cf81dSBarry Smith Notes: 2608e35cf81dSBarry Smith The default is 1 2609e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2610fe3ffe1eSBarry 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 2611fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2612e35cf81dSBarry Smith 2613e35cf81dSBarry Smith Level: intermediate 2614e35cf81dSBarry Smith 2615e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2616e35cf81dSBarry Smith 2617e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2618e35cf81dSBarry Smith 2619e35cf81dSBarry Smith @*/ 26207087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2621e35cf81dSBarry Smith { 2622e35cf81dSBarry Smith PetscFunctionBegin; 26230700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2624e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2625e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2626c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2627e35cf81dSBarry Smith snes->lagjacobian = lag; 2628e35cf81dSBarry Smith PetscFunctionReturn(0); 2629e35cf81dSBarry Smith } 2630e35cf81dSBarry Smith 2631e35cf81dSBarry Smith #undef __FUNCT__ 2632e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2633e35cf81dSBarry Smith /*@ 2634e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2635e35cf81dSBarry Smith 26363f9fe445SBarry Smith Not Collective 2637e35cf81dSBarry Smith 2638e35cf81dSBarry Smith Input Parameter: 2639e35cf81dSBarry Smith . snes - the SNES context 2640e35cf81dSBarry Smith 2641e35cf81dSBarry Smith Output Parameter: 2642e35cf81dSBarry 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 2643e35cf81dSBarry Smith the Jacobian is built etc. 2644e35cf81dSBarry Smith 2645e35cf81dSBarry Smith Options Database Keys: 2646e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2647e35cf81dSBarry Smith 2648e35cf81dSBarry Smith Notes: 2649e35cf81dSBarry Smith The default is 1 2650e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2651e35cf81dSBarry Smith 2652e35cf81dSBarry Smith Level: intermediate 2653e35cf81dSBarry Smith 2654e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2655e35cf81dSBarry Smith 2656e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2657e35cf81dSBarry Smith 2658e35cf81dSBarry Smith @*/ 26597087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2660e35cf81dSBarry Smith { 2661e35cf81dSBarry Smith PetscFunctionBegin; 26620700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2663e35cf81dSBarry Smith *lag = snes->lagjacobian; 2664e35cf81dSBarry Smith PetscFunctionReturn(0); 2665e35cf81dSBarry Smith } 2666e35cf81dSBarry Smith 2667e35cf81dSBarry Smith #undef __FUNCT__ 26684a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 26699b94acceSBarry Smith /*@ 2670d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 26719b94acceSBarry Smith 26723f9fe445SBarry Smith Logically Collective on SNES 2673c7afd0dbSLois Curfman McInnes 26749b94acceSBarry Smith Input Parameters: 2675c7afd0dbSLois Curfman McInnes + snes - the SNES context 267670441072SBarry Smith . abstol - absolute convergence tolerance 267733174efeSLois Curfman McInnes . rtol - relative convergence tolerance 267833174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 267933174efeSLois Curfman McInnes of the change in the solution between steps 268033174efeSLois Curfman McInnes . maxit - maximum number of iterations 2681c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2682fee21e36SBarry Smith 268333174efeSLois Curfman McInnes Options Database Keys: 268470441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2685c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2686c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2687c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2688c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 26899b94acceSBarry Smith 2690d7a720efSLois Curfman McInnes Notes: 26919b94acceSBarry Smith The default maximum number of iterations is 50. 26929b94acceSBarry Smith The default maximum number of function evaluations is 1000. 26939b94acceSBarry Smith 269436851e7fSLois Curfman McInnes Level: intermediate 269536851e7fSLois Curfman McInnes 269633174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 26979b94acceSBarry Smith 26982492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 26999b94acceSBarry Smith @*/ 27007087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 27019b94acceSBarry Smith { 27023a40ed3dSBarry Smith PetscFunctionBegin; 27030700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2704c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2705c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2706c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2707c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2708c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2709c5eb9154SBarry Smith 2710ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2711ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2712ab54825eSJed Brown snes->abstol = abstol; 2713ab54825eSJed Brown } 2714ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2715ab54825eSJed 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); 2716ab54825eSJed Brown snes->rtol = rtol; 2717ab54825eSJed Brown } 2718ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2719ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2720c60f73f4SPeter Brune snes->stol = stol; 2721ab54825eSJed Brown } 2722ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2723ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2724ab54825eSJed Brown snes->max_its = maxit; 2725ab54825eSJed Brown } 2726ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2727ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2728ab54825eSJed Brown snes->max_funcs = maxf; 2729ab54825eSJed Brown } 273088976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 27313a40ed3dSBarry Smith PetscFunctionReturn(0); 27329b94acceSBarry Smith } 27339b94acceSBarry Smith 27344a2ae208SSatish Balay #undef __FUNCT__ 27354a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 27369b94acceSBarry Smith /*@ 273733174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 273833174efeSLois Curfman McInnes 2739c7afd0dbSLois Curfman McInnes Not Collective 2740c7afd0dbSLois Curfman McInnes 274133174efeSLois Curfman McInnes Input Parameters: 2742c7afd0dbSLois Curfman McInnes + snes - the SNES context 274385385478SLisandro Dalcin . atol - absolute convergence tolerance 274433174efeSLois Curfman McInnes . rtol - relative convergence tolerance 274533174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 274633174efeSLois Curfman McInnes of the change in the solution between steps 274733174efeSLois Curfman McInnes . maxit - maximum number of iterations 2748c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2749fee21e36SBarry Smith 275033174efeSLois Curfman McInnes Notes: 275133174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 275233174efeSLois Curfman McInnes 275336851e7fSLois Curfman McInnes Level: intermediate 275436851e7fSLois Curfman McInnes 275533174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 275633174efeSLois Curfman McInnes 275733174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 275833174efeSLois Curfman McInnes @*/ 27597087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 276033174efeSLois Curfman McInnes { 27613a40ed3dSBarry Smith PetscFunctionBegin; 27620700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 276385385478SLisandro Dalcin if (atol) *atol = snes->abstol; 276433174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 2765c60f73f4SPeter Brune if (stol) *stol = snes->stol; 276633174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 276733174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 27683a40ed3dSBarry Smith PetscFunctionReturn(0); 276933174efeSLois Curfman McInnes } 277033174efeSLois Curfman McInnes 27714a2ae208SSatish Balay #undef __FUNCT__ 27724a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 277333174efeSLois Curfman McInnes /*@ 27749b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 27759b94acceSBarry Smith 27763f9fe445SBarry Smith Logically Collective on SNES 2777fee21e36SBarry Smith 2778c7afd0dbSLois Curfman McInnes Input Parameters: 2779c7afd0dbSLois Curfman McInnes + snes - the SNES context 2780c7afd0dbSLois Curfman McInnes - tol - tolerance 2781c7afd0dbSLois Curfman McInnes 27829b94acceSBarry Smith Options Database Key: 2783c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 27849b94acceSBarry Smith 278536851e7fSLois Curfman McInnes Level: intermediate 278636851e7fSLois Curfman McInnes 27879b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 27889b94acceSBarry Smith 27892492ecdbSBarry Smith .seealso: SNESSetTolerances() 27909b94acceSBarry Smith @*/ 27917087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 27929b94acceSBarry Smith { 27933a40ed3dSBarry Smith PetscFunctionBegin; 27940700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2795c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 27969b94acceSBarry Smith snes->deltatol = tol; 27973a40ed3dSBarry Smith PetscFunctionReturn(0); 27989b94acceSBarry Smith } 27999b94acceSBarry Smith 2800df9fa365SBarry Smith /* 2801df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2802df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2803df9fa365SBarry Smith macros instead of functions 2804df9fa365SBarry Smith */ 28054a2ae208SSatish Balay #undef __FUNCT__ 2806a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 28077087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2808ce1608b8SBarry Smith { 2809dfbe8321SBarry Smith PetscErrorCode ierr; 2810ce1608b8SBarry Smith 2811ce1608b8SBarry Smith PetscFunctionBegin; 28120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2813a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2814ce1608b8SBarry Smith PetscFunctionReturn(0); 2815ce1608b8SBarry Smith } 2816ce1608b8SBarry Smith 28174a2ae208SSatish Balay #undef __FUNCT__ 2818a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 28197087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2820df9fa365SBarry Smith { 2821dfbe8321SBarry Smith PetscErrorCode ierr; 2822df9fa365SBarry Smith 2823df9fa365SBarry Smith PetscFunctionBegin; 2824a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2825df9fa365SBarry Smith PetscFunctionReturn(0); 2826df9fa365SBarry Smith } 2827df9fa365SBarry Smith 28284a2ae208SSatish Balay #undef __FUNCT__ 2829a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 28306bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2831df9fa365SBarry Smith { 2832dfbe8321SBarry Smith PetscErrorCode ierr; 2833df9fa365SBarry Smith 2834df9fa365SBarry Smith PetscFunctionBegin; 2835a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2836df9fa365SBarry Smith PetscFunctionReturn(0); 2837df9fa365SBarry Smith } 2838df9fa365SBarry Smith 28397087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2840b271bb04SBarry Smith #undef __FUNCT__ 2841b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 28427087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2843b271bb04SBarry Smith { 2844b271bb04SBarry Smith PetscDrawLG lg; 2845b271bb04SBarry Smith PetscErrorCode ierr; 2846b271bb04SBarry Smith PetscReal x,y,per; 2847b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2848b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2849b271bb04SBarry Smith PetscDraw draw; 2850b271bb04SBarry Smith PetscFunctionBegin; 2851b271bb04SBarry Smith if (!monctx) { 2852b271bb04SBarry Smith MPI_Comm comm; 2853b271bb04SBarry Smith 2854b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2855b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2856b271bb04SBarry Smith } 2857b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2858b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2859b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2860b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2861b271bb04SBarry Smith x = (PetscReal) n; 2862b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2863b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2864b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2865b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2866b271bb04SBarry Smith } 2867b271bb04SBarry Smith 2868b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2869b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2870b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2871b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2872b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2873b271bb04SBarry Smith x = (PetscReal) n; 2874b271bb04SBarry Smith y = 100.0*per; 2875b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2876b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2877b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2878b271bb04SBarry Smith } 2879b271bb04SBarry Smith 2880b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2881b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2882b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2883b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2884b271bb04SBarry Smith x = (PetscReal) n; 2885b271bb04SBarry Smith y = (prev - rnorm)/prev; 2886b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2887b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2888b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2889b271bb04SBarry Smith } 2890b271bb04SBarry Smith 2891b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2892b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2893b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2894b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2895b271bb04SBarry Smith x = (PetscReal) n; 2896b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2897b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2898b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2899b271bb04SBarry Smith } 2900b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2901b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2902b271bb04SBarry Smith } 2903b271bb04SBarry Smith prev = rnorm; 2904b271bb04SBarry Smith PetscFunctionReturn(0); 2905b271bb04SBarry Smith } 2906b271bb04SBarry Smith 2907b271bb04SBarry Smith #undef __FUNCT__ 2908b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 29097087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2910b271bb04SBarry Smith { 2911b271bb04SBarry Smith PetscErrorCode ierr; 2912b271bb04SBarry Smith 2913b271bb04SBarry Smith PetscFunctionBegin; 2914b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2915b271bb04SBarry Smith PetscFunctionReturn(0); 2916b271bb04SBarry Smith } 2917b271bb04SBarry Smith 2918b271bb04SBarry Smith #undef __FUNCT__ 2919b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 29206bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2921b271bb04SBarry Smith { 2922b271bb04SBarry Smith PetscErrorCode ierr; 2923b271bb04SBarry Smith 2924b271bb04SBarry Smith PetscFunctionBegin; 2925b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2926b271bb04SBarry Smith PetscFunctionReturn(0); 2927b271bb04SBarry Smith } 2928b271bb04SBarry Smith 29297a03ce2fSLisandro Dalcin #undef __FUNCT__ 29307a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 2931228d79bcSJed Brown /*@ 2932228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 2933228d79bcSJed Brown 2934228d79bcSJed Brown Collective on SNES 2935228d79bcSJed Brown 2936228d79bcSJed Brown Input Parameters: 2937228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 2938228d79bcSJed Brown . iter - iteration number 2939228d79bcSJed Brown - rnorm - relative norm of the residual 2940228d79bcSJed Brown 2941228d79bcSJed Brown Notes: 2942228d79bcSJed Brown This routine is called by the SNES implementations. 2943228d79bcSJed Brown It does not typically need to be called by the user. 2944228d79bcSJed Brown 2945228d79bcSJed Brown Level: developer 2946228d79bcSJed Brown 2947228d79bcSJed Brown .seealso: SNESMonitorSet() 2948228d79bcSJed Brown @*/ 29497a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 29507a03ce2fSLisandro Dalcin { 29517a03ce2fSLisandro Dalcin PetscErrorCode ierr; 29527a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 29537a03ce2fSLisandro Dalcin 29547a03ce2fSLisandro Dalcin PetscFunctionBegin; 29557a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 29567a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 29577a03ce2fSLisandro Dalcin } 29587a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 29597a03ce2fSLisandro Dalcin } 29607a03ce2fSLisandro Dalcin 29619b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 29629b94acceSBarry Smith 29634a2ae208SSatish Balay #undef __FUNCT__ 2964a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 29659b94acceSBarry Smith /*@C 2966a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 29679b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 29689b94acceSBarry Smith progress. 29699b94acceSBarry Smith 29703f9fe445SBarry Smith Logically Collective on SNES 2971fee21e36SBarry Smith 2972c7afd0dbSLois Curfman McInnes Input Parameters: 2973c7afd0dbSLois Curfman McInnes + snes - the SNES context 2974c7afd0dbSLois Curfman McInnes . func - monitoring routine 2975b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 2976e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 2977b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 2978b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 29799b94acceSBarry Smith 2980c7afd0dbSLois Curfman McInnes Calling sequence of func: 2981a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2982c7afd0dbSLois Curfman McInnes 2983c7afd0dbSLois Curfman McInnes + snes - the SNES context 2984c7afd0dbSLois Curfman McInnes . its - iteration number 2985c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 298640a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 29879b94acceSBarry Smith 29889665c990SLois Curfman McInnes Options Database Keys: 2989a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 2990a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 2991a6570f20SBarry Smith uses SNESMonitorLGCreate() 2992cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 2993c7afd0dbSLois Curfman McInnes been hardwired into a code by 2994a6570f20SBarry Smith calls to SNESMonitorSet(), but 2995c7afd0dbSLois Curfman McInnes does not cancel those set via 2996c7afd0dbSLois Curfman McInnes the options database. 29979665c990SLois Curfman McInnes 2998639f9d9dSBarry Smith Notes: 29996bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 3000a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 30016bc08f3fSLois Curfman McInnes order in which they were set. 3002639f9d9dSBarry Smith 3003025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 3004025f1a04SBarry Smith 300536851e7fSLois Curfman McInnes Level: intermediate 300636851e7fSLois Curfman McInnes 30079b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 30089b94acceSBarry Smith 3009a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 30109b94acceSBarry Smith @*/ 3011c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 30129b94acceSBarry Smith { 3013b90d0a6eSBarry Smith PetscInt i; 3014649052a6SBarry Smith PetscErrorCode ierr; 3015b90d0a6eSBarry Smith 30163a40ed3dSBarry Smith PetscFunctionBegin; 30170700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 301817186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 3019b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 3020649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 3021649052a6SBarry Smith if (monitordestroy) { 3022c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 3023649052a6SBarry Smith } 3024b90d0a6eSBarry Smith PetscFunctionReturn(0); 3025b90d0a6eSBarry Smith } 3026b90d0a6eSBarry Smith } 3027b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 3028b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 3029639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 30303a40ed3dSBarry Smith PetscFunctionReturn(0); 30319b94acceSBarry Smith } 30329b94acceSBarry Smith 30334a2ae208SSatish Balay #undef __FUNCT__ 3034a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 30355cd90555SBarry Smith /*@C 3036a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 30375cd90555SBarry Smith 30383f9fe445SBarry Smith Logically Collective on SNES 3039c7afd0dbSLois Curfman McInnes 30405cd90555SBarry Smith Input Parameters: 30415cd90555SBarry Smith . snes - the SNES context 30425cd90555SBarry Smith 30431a480d89SAdministrator Options Database Key: 3044a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 3045a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 3046c7afd0dbSLois Curfman McInnes set via the options database 30475cd90555SBarry Smith 30485cd90555SBarry Smith Notes: 30495cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 30505cd90555SBarry Smith 305136851e7fSLois Curfman McInnes Level: intermediate 305236851e7fSLois Curfman McInnes 30535cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 30545cd90555SBarry Smith 3055a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 30565cd90555SBarry Smith @*/ 30577087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 30585cd90555SBarry Smith { 3059d952e501SBarry Smith PetscErrorCode ierr; 3060d952e501SBarry Smith PetscInt i; 3061d952e501SBarry Smith 30625cd90555SBarry Smith PetscFunctionBegin; 30630700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3064d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 3065d952e501SBarry Smith if (snes->monitordestroy[i]) { 30663c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 3067d952e501SBarry Smith } 3068d952e501SBarry Smith } 30695cd90555SBarry Smith snes->numbermonitors = 0; 30705cd90555SBarry Smith PetscFunctionReturn(0); 30715cd90555SBarry Smith } 30725cd90555SBarry Smith 30734a2ae208SSatish Balay #undef __FUNCT__ 30744a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 30759b94acceSBarry Smith /*@C 30769b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 30779b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 30789b94acceSBarry Smith 30793f9fe445SBarry Smith Logically Collective on SNES 3080fee21e36SBarry Smith 3081c7afd0dbSLois Curfman McInnes Input Parameters: 3082c7afd0dbSLois Curfman McInnes + snes - the SNES context 3083c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 30847f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 30857f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 30869b94acceSBarry Smith 3087c7afd0dbSLois Curfman McInnes Calling sequence of func: 308806ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 3089c7afd0dbSLois Curfman McInnes 3090c7afd0dbSLois Curfman McInnes + snes - the SNES context 309106ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 3092c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 3093184914b5SBarry Smith . reason - reason for convergence/divergence 3094c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 30954b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 30964b27c08aSLois Curfman McInnes - f - 2-norm of function 30979b94acceSBarry Smith 309836851e7fSLois Curfman McInnes Level: advanced 309936851e7fSLois Curfman McInnes 31009b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 31019b94acceSBarry Smith 310285385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 31039b94acceSBarry Smith @*/ 31047087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 31059b94acceSBarry Smith { 31067f7931b9SBarry Smith PetscErrorCode ierr; 31077f7931b9SBarry Smith 31083a40ed3dSBarry Smith PetscFunctionBegin; 31090700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 311085385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 31117f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 31127f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 31137f7931b9SBarry Smith } 311485385478SLisandro Dalcin snes->ops->converged = func; 31157f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 311685385478SLisandro Dalcin snes->cnvP = cctx; 31173a40ed3dSBarry Smith PetscFunctionReturn(0); 31189b94acceSBarry Smith } 31199b94acceSBarry Smith 31204a2ae208SSatish Balay #undef __FUNCT__ 31214a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 312252baeb72SSatish Balay /*@ 3123184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 3124184914b5SBarry Smith 3125184914b5SBarry Smith Not Collective 3126184914b5SBarry Smith 3127184914b5SBarry Smith Input Parameter: 3128184914b5SBarry Smith . snes - the SNES context 3129184914b5SBarry Smith 3130184914b5SBarry Smith Output Parameter: 31314d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 3132184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 3133184914b5SBarry Smith 3134184914b5SBarry Smith Level: intermediate 3135184914b5SBarry Smith 3136184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 3137184914b5SBarry Smith 3138184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 3139184914b5SBarry Smith 314085385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 3141184914b5SBarry Smith @*/ 31427087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 3143184914b5SBarry Smith { 3144184914b5SBarry Smith PetscFunctionBegin; 31450700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31464482741eSBarry Smith PetscValidPointer(reason,2); 3147184914b5SBarry Smith *reason = snes->reason; 3148184914b5SBarry Smith PetscFunctionReturn(0); 3149184914b5SBarry Smith } 3150184914b5SBarry Smith 31514a2ae208SSatish Balay #undef __FUNCT__ 31524a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 3153c9005455SLois Curfman McInnes /*@ 3154c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 3155c9005455SLois Curfman McInnes 31563f9fe445SBarry Smith Logically Collective on SNES 3157fee21e36SBarry Smith 3158c7afd0dbSLois Curfman McInnes Input Parameters: 3159c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 31608c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 3161cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 3162758f92a0SBarry Smith . na - size of a and its 316364731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 3164758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 3165c7afd0dbSLois Curfman McInnes 3166308dcc3eSBarry Smith Notes: 3167308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 3168308dcc3eSBarry Smith default array of length 10000 is allocated. 3169308dcc3eSBarry Smith 3170c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 3171c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 3172c9005455SLois Curfman McInnes during the section of code that is being timed. 3173c9005455SLois Curfman McInnes 317436851e7fSLois Curfman McInnes Level: intermediate 317536851e7fSLois Curfman McInnes 3176c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 3177758f92a0SBarry Smith 317808405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 3179758f92a0SBarry Smith 3180c9005455SLois Curfman McInnes @*/ 31817087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 3182c9005455SLois Curfman McInnes { 3183308dcc3eSBarry Smith PetscErrorCode ierr; 3184308dcc3eSBarry Smith 31853a40ed3dSBarry Smith PetscFunctionBegin; 31860700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31874482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 3188a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 3189308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 3190308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 3191308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 3192308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 3193308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 3194308dcc3eSBarry Smith } 3195c9005455SLois Curfman McInnes snes->conv_hist = a; 3196758f92a0SBarry Smith snes->conv_hist_its = its; 3197758f92a0SBarry Smith snes->conv_hist_max = na; 3198a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 3199758f92a0SBarry Smith snes->conv_hist_reset = reset; 3200758f92a0SBarry Smith PetscFunctionReturn(0); 3201758f92a0SBarry Smith } 3202758f92a0SBarry Smith 3203308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3204c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 3205c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 3206308dcc3eSBarry Smith EXTERN_C_BEGIN 3207308dcc3eSBarry Smith #undef __FUNCT__ 3208308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 3209308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3210308dcc3eSBarry Smith { 3211308dcc3eSBarry Smith mxArray *mat; 3212308dcc3eSBarry Smith PetscInt i; 3213308dcc3eSBarry Smith PetscReal *ar; 3214308dcc3eSBarry Smith 3215308dcc3eSBarry Smith PetscFunctionBegin; 3216308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3217308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3218308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 3219308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 3220308dcc3eSBarry Smith } 3221308dcc3eSBarry Smith PetscFunctionReturn(mat); 3222308dcc3eSBarry Smith } 3223308dcc3eSBarry Smith EXTERN_C_END 3224308dcc3eSBarry Smith #endif 3225308dcc3eSBarry Smith 3226308dcc3eSBarry Smith 32274a2ae208SSatish Balay #undef __FUNCT__ 32284a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 32290c4c9dddSBarry Smith /*@C 3230758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3231758f92a0SBarry Smith 32323f9fe445SBarry Smith Not Collective 3233758f92a0SBarry Smith 3234758f92a0SBarry Smith Input Parameter: 3235758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3236758f92a0SBarry Smith 3237758f92a0SBarry Smith Output Parameters: 3238758f92a0SBarry Smith . a - array to hold history 3239758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3240758f92a0SBarry Smith negative if not converged) for each solve. 3241758f92a0SBarry Smith - na - size of a and its 3242758f92a0SBarry Smith 3243758f92a0SBarry Smith Notes: 3244758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3245758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3246758f92a0SBarry Smith 3247758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3248758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3249758f92a0SBarry Smith during the section of code that is being timed. 3250758f92a0SBarry Smith 3251758f92a0SBarry Smith Level: intermediate 3252758f92a0SBarry Smith 3253758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3254758f92a0SBarry Smith 3255758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3256758f92a0SBarry Smith 3257758f92a0SBarry Smith @*/ 32587087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3259758f92a0SBarry Smith { 3260758f92a0SBarry Smith PetscFunctionBegin; 32610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3262758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3263758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3264758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 32653a40ed3dSBarry Smith PetscFunctionReturn(0); 3266c9005455SLois Curfman McInnes } 3267c9005455SLois Curfman McInnes 3268e74ef692SMatthew Knepley #undef __FUNCT__ 3269e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 3270ac226902SBarry Smith /*@C 327176b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3272eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 32737e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 327476b2cf59SMatthew Knepley 32753f9fe445SBarry Smith Logically Collective on SNES 327676b2cf59SMatthew Knepley 327776b2cf59SMatthew Knepley Input Parameters: 327876b2cf59SMatthew Knepley . snes - The nonlinear solver context 327976b2cf59SMatthew Knepley . func - The function 328076b2cf59SMatthew Knepley 328176b2cf59SMatthew Knepley Calling sequence of func: 3282b5d30489SBarry Smith . func (SNES snes, PetscInt step); 328376b2cf59SMatthew Knepley 328476b2cf59SMatthew Knepley . step - The current step of the iteration 328576b2cf59SMatthew Knepley 3286fe97e370SBarry Smith Level: advanced 3287fe97e370SBarry Smith 3288fe97e370SBarry 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() 3289fe97e370SBarry Smith This is not used by most users. 329076b2cf59SMatthew Knepley 329176b2cf59SMatthew Knepley .keywords: SNES, update 3292b5d30489SBarry Smith 329385385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 329476b2cf59SMatthew Knepley @*/ 32957087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 329676b2cf59SMatthew Knepley { 329776b2cf59SMatthew Knepley PetscFunctionBegin; 32980700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3299e7788613SBarry Smith snes->ops->update = func; 330076b2cf59SMatthew Knepley PetscFunctionReturn(0); 330176b2cf59SMatthew Knepley } 330276b2cf59SMatthew Knepley 3303e74ef692SMatthew Knepley #undef __FUNCT__ 3304e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 330576b2cf59SMatthew Knepley /*@ 330676b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 330776b2cf59SMatthew Knepley 330876b2cf59SMatthew Knepley Not collective 330976b2cf59SMatthew Knepley 331076b2cf59SMatthew Knepley Input Parameters: 331176b2cf59SMatthew Knepley . snes - The nonlinear solver context 331276b2cf59SMatthew Knepley . step - The current step of the iteration 331376b2cf59SMatthew Knepley 3314205452f4SMatthew Knepley Level: intermediate 3315205452f4SMatthew Knepley 331676b2cf59SMatthew Knepley .keywords: SNES, update 3317a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 331876b2cf59SMatthew Knepley @*/ 33197087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 332076b2cf59SMatthew Knepley { 332176b2cf59SMatthew Knepley PetscFunctionBegin; 332276b2cf59SMatthew Knepley PetscFunctionReturn(0); 332376b2cf59SMatthew Knepley } 332476b2cf59SMatthew Knepley 33254a2ae208SSatish Balay #undef __FUNCT__ 33264a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 33279b94acceSBarry Smith /* 33289b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 33299b94acceSBarry Smith positive parameter delta. 33309b94acceSBarry Smith 33319b94acceSBarry Smith Input Parameters: 3332c7afd0dbSLois Curfman McInnes + snes - the SNES context 33339b94acceSBarry Smith . y - approximate solution of linear system 33349b94acceSBarry Smith . fnorm - 2-norm of current function 3335c7afd0dbSLois Curfman McInnes - delta - trust region size 33369b94acceSBarry Smith 33379b94acceSBarry Smith Output Parameters: 3338c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 33399b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 33409b94acceSBarry Smith region, and exceeds zero otherwise. 3341c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 33429b94acceSBarry Smith 33439b94acceSBarry Smith Note: 33444b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 33459b94acceSBarry Smith is set to be the maximum allowable step size. 33469b94acceSBarry Smith 33479b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 33489b94acceSBarry Smith */ 3349dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 33509b94acceSBarry Smith { 3351064f8208SBarry Smith PetscReal nrm; 3352ea709b57SSatish Balay PetscScalar cnorm; 3353dfbe8321SBarry Smith PetscErrorCode ierr; 33543a40ed3dSBarry Smith 33553a40ed3dSBarry Smith PetscFunctionBegin; 33560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 33570700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3358c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3359184914b5SBarry Smith 3360064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3361064f8208SBarry Smith if (nrm > *delta) { 3362064f8208SBarry Smith nrm = *delta/nrm; 3363064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3364064f8208SBarry Smith cnorm = nrm; 33652dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 33669b94acceSBarry Smith *ynorm = *delta; 33679b94acceSBarry Smith } else { 33689b94acceSBarry Smith *gpnorm = 0.0; 3369064f8208SBarry Smith *ynorm = nrm; 33709b94acceSBarry Smith } 33713a40ed3dSBarry Smith PetscFunctionReturn(0); 33729b94acceSBarry Smith } 33739b94acceSBarry Smith 33744a2ae208SSatish Balay #undef __FUNCT__ 33754a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 33766ce558aeSBarry Smith /*@C 3377f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3378f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 33799b94acceSBarry Smith 3380c7afd0dbSLois Curfman McInnes Collective on SNES 3381c7afd0dbSLois Curfman McInnes 3382b2002411SLois Curfman McInnes Input Parameters: 3383c7afd0dbSLois Curfman McInnes + snes - the SNES context 33843cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 338585385478SLisandro Dalcin - x - the solution vector. 33869b94acceSBarry Smith 3387b2002411SLois Curfman McInnes Notes: 33888ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 33898ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 33908ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 33918ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 33928ddd3da0SLois Curfman McInnes 339336851e7fSLois Curfman McInnes Level: beginner 339436851e7fSLois Curfman McInnes 33959b94acceSBarry Smith .keywords: SNES, nonlinear, solve 33969b94acceSBarry Smith 3397c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 33989b94acceSBarry Smith @*/ 33997087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 34009b94acceSBarry Smith { 3401dfbe8321SBarry Smith PetscErrorCode ierr; 3402ace3abfcSBarry Smith PetscBool flg; 3403eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 3404eabae89aSBarry Smith PetscViewer viewer; 3405efd51863SBarry Smith PetscInt grid; 3406a69afd8bSBarry Smith Vec xcreated = PETSC_NULL; 3407caa4e7f2SJed Brown DM dm; 3408052efed2SBarry Smith 34093a40ed3dSBarry Smith PetscFunctionBegin; 34100700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3411a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3412a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 34130700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 341485385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 341585385478SLisandro Dalcin 3416caa4e7f2SJed Brown if (!x) { 3417caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3418caa4e7f2SJed Brown ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 3419a69afd8bSBarry Smith x = xcreated; 3420a69afd8bSBarry Smith } 3421a69afd8bSBarry Smith 3422a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3423efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3424efd51863SBarry Smith 342585385478SLisandro Dalcin /* set solution vector */ 3426efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 34276bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 342885385478SLisandro Dalcin snes->vec_sol = x; 3429caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3430caa4e7f2SJed Brown 3431caa4e7f2SJed Brown /* set affine vector if provided */ 343285385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 34336bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 343485385478SLisandro Dalcin snes->vec_rhs = b; 343585385478SLisandro Dalcin 343670e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 34373f149594SLisandro Dalcin 34387eee914bSBarry Smith if (!grid) { 34397eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3440d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3441dd568438SSatish Balay } else if (snes->dm) { 3442dd568438SSatish Balay PetscBool ig; 3443dd568438SSatish Balay ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr); 3444dd568438SSatish Balay if (ig) { 34457eee914bSBarry Smith ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr); 34467eee914bSBarry Smith } 3447d25893d9SBarry Smith } 3448dd568438SSatish Balay } 3449d25893d9SBarry Smith 3450abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 345150ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3452d5e45103SBarry Smith 34533f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 34544936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 345585385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 34564936397dSBarry Smith if (snes->domainerror){ 34574936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 34584936397dSBarry Smith snes->domainerror = PETSC_FALSE; 34594936397dSBarry Smith } 346017186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 34613f149594SLisandro Dalcin 34627adad957SLisandro Dalcin ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 3463eabae89aSBarry Smith if (flg && !PetscPreLoadingOn) { 34647adad957SLisandro Dalcin ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 3465eabae89aSBarry Smith ierr = SNESView(snes,viewer);CHKERRQ(ierr); 34666bf464f9SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3467eabae89aSBarry Smith } 3468eabae89aSBarry Smith 346990d69ab7SBarry Smith flg = PETSC_FALSE; 3470acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3471da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 34725968eb51SBarry Smith if (snes->printreason) { 3473a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 34745968eb51SBarry Smith if (snes->reason > 0) { 3475c7e7b494SJed 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); 34765968eb51SBarry Smith } else { 3477c7e7b494SJed 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); 34785968eb51SBarry Smith } 3479a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 34805968eb51SBarry Smith } 34815968eb51SBarry Smith 34828501fc72SJed Brown flg = PETSC_FALSE; 34838501fc72SJed Brown ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 34848501fc72SJed Brown if (flg) { 34858501fc72SJed Brown PetscViewer viewer; 34868501fc72SJed Brown ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 34878501fc72SJed Brown ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 34888501fc72SJed Brown ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 34898501fc72SJed Brown ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 34908501fc72SJed Brown ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 34918501fc72SJed Brown } 34928501fc72SJed Brown 3493e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3494efd51863SBarry Smith if (grid < snes->gridsequence) { 3495efd51863SBarry Smith DM fine; 3496efd51863SBarry Smith Vec xnew; 3497efd51863SBarry Smith Mat interp; 3498efd51863SBarry Smith 3499efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3500c5c77316SJed Brown if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 3501e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3502efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3503efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3504efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3505efd51863SBarry Smith x = xnew; 3506efd51863SBarry Smith 3507efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3508efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3509efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3510a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3511efd51863SBarry Smith } 3512efd51863SBarry Smith } 3513a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 35143a40ed3dSBarry Smith PetscFunctionReturn(0); 35159b94acceSBarry Smith } 35169b94acceSBarry Smith 35179b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 35189b94acceSBarry Smith 35194a2ae208SSatish Balay #undef __FUNCT__ 35204a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 352182bf6240SBarry Smith /*@C 35224b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 35239b94acceSBarry Smith 3524fee21e36SBarry Smith Collective on SNES 3525fee21e36SBarry Smith 3526c7afd0dbSLois Curfman McInnes Input Parameters: 3527c7afd0dbSLois Curfman McInnes + snes - the SNES context 3528454a90a3SBarry Smith - type - a known method 3529c7afd0dbSLois Curfman McInnes 3530c7afd0dbSLois Curfman McInnes Options Database Key: 3531454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3532c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3533ae12b187SLois Curfman McInnes 35349b94acceSBarry Smith Notes: 3535e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 35364b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3537c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 35384b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3539c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 35409b94acceSBarry Smith 3541ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3542ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3543ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3544ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3545ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3546ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3547ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3548ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3549ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3550b0a32e0cSBarry Smith appropriate method. 355136851e7fSLois Curfman McInnes 355236851e7fSLois Curfman McInnes Level: intermediate 3553a703fe33SLois Curfman McInnes 3554454a90a3SBarry Smith .keywords: SNES, set, type 3555435da068SBarry Smith 3556435da068SBarry Smith .seealso: SNESType, SNESCreate() 3557435da068SBarry Smith 35589b94acceSBarry Smith @*/ 35597087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 35609b94acceSBarry Smith { 3561dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3562ace3abfcSBarry Smith PetscBool match; 35633a40ed3dSBarry Smith 35643a40ed3dSBarry Smith PetscFunctionBegin; 35650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35664482741eSBarry Smith PetscValidCharPointer(type,2); 356782bf6240SBarry Smith 35686831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 35690f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 357092ff6ae8SBarry Smith 35714b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3572e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 357375396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 3574b5c23020SJed Brown if (snes->ops->destroy) { 3575b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 3576b5c23020SJed Brown snes->ops->destroy = PETSC_NULL; 3577b5c23020SJed Brown } 357875396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 357975396ef9SLisandro Dalcin snes->ops->setup = 0; 358075396ef9SLisandro Dalcin snes->ops->solve = 0; 358175396ef9SLisandro Dalcin snes->ops->view = 0; 358275396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 358375396ef9SLisandro Dalcin snes->ops->destroy = 0; 358475396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 358575396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3586454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 358703bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 35889fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 35899fb22e1aSBarry Smith if (PetscAMSPublishAll) { 35909fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 35919fb22e1aSBarry Smith } 35929fb22e1aSBarry Smith #endif 35933a40ed3dSBarry Smith PetscFunctionReturn(0); 35949b94acceSBarry Smith } 35959b94acceSBarry Smith 3596a847f771SSatish Balay 35979b94acceSBarry Smith /* --------------------------------------------------------------------- */ 35984a2ae208SSatish Balay #undef __FUNCT__ 35994a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 360052baeb72SSatish Balay /*@ 36019b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3602f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 36039b94acceSBarry Smith 3604fee21e36SBarry Smith Not Collective 3605fee21e36SBarry Smith 360636851e7fSLois Curfman McInnes Level: advanced 360736851e7fSLois Curfman McInnes 36089b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 36099b94acceSBarry Smith 36109b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 36119b94acceSBarry Smith @*/ 36127087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 36139b94acceSBarry Smith { 3614dfbe8321SBarry Smith PetscErrorCode ierr; 361582bf6240SBarry Smith 36163a40ed3dSBarry Smith PetscFunctionBegin; 36171441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 36184c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 36193a40ed3dSBarry Smith PetscFunctionReturn(0); 36209b94acceSBarry Smith } 36219b94acceSBarry Smith 36224a2ae208SSatish Balay #undef __FUNCT__ 36234a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 36249b94acceSBarry Smith /*@C 36259a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 36269b94acceSBarry Smith 3627c7afd0dbSLois Curfman McInnes Not Collective 3628c7afd0dbSLois Curfman McInnes 36299b94acceSBarry Smith Input Parameter: 36304b0e389bSBarry Smith . snes - nonlinear solver context 36319b94acceSBarry Smith 36329b94acceSBarry Smith Output Parameter: 36333a7fca6bSBarry Smith . type - SNES method (a character string) 36349b94acceSBarry Smith 363536851e7fSLois Curfman McInnes Level: intermediate 363636851e7fSLois Curfman McInnes 3637454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 36389b94acceSBarry Smith @*/ 36397087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 36409b94acceSBarry Smith { 36413a40ed3dSBarry Smith PetscFunctionBegin; 36420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36434482741eSBarry Smith PetscValidPointer(type,2); 36447adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 36453a40ed3dSBarry Smith PetscFunctionReturn(0); 36469b94acceSBarry Smith } 36479b94acceSBarry Smith 36484a2ae208SSatish Balay #undef __FUNCT__ 36494a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 365052baeb72SSatish Balay /*@ 36519b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3652c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 36539b94acceSBarry Smith 3654c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3655c7afd0dbSLois Curfman McInnes 36569b94acceSBarry Smith Input Parameter: 36579b94acceSBarry Smith . snes - the SNES context 36589b94acceSBarry Smith 36599b94acceSBarry Smith Output Parameter: 36609b94acceSBarry Smith . x - the solution 36619b94acceSBarry Smith 366270e92668SMatthew Knepley Level: intermediate 366336851e7fSLois Curfman McInnes 36649b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 36659b94acceSBarry Smith 366685385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 36679b94acceSBarry Smith @*/ 36687087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 36699b94acceSBarry Smith { 36703a40ed3dSBarry Smith PetscFunctionBegin; 36710700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36724482741eSBarry Smith PetscValidPointer(x,2); 367385385478SLisandro Dalcin *x = snes->vec_sol; 367470e92668SMatthew Knepley PetscFunctionReturn(0); 367570e92668SMatthew Knepley } 367670e92668SMatthew Knepley 367770e92668SMatthew Knepley #undef __FUNCT__ 36784a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 367952baeb72SSatish Balay /*@ 36809b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 36819b94acceSBarry Smith stored. 36829b94acceSBarry Smith 3683c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3684c7afd0dbSLois Curfman McInnes 36859b94acceSBarry Smith Input Parameter: 36869b94acceSBarry Smith . snes - the SNES context 36879b94acceSBarry Smith 36889b94acceSBarry Smith Output Parameter: 36899b94acceSBarry Smith . x - the solution update 36909b94acceSBarry Smith 369136851e7fSLois Curfman McInnes Level: advanced 369236851e7fSLois Curfman McInnes 36939b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 36949b94acceSBarry Smith 369585385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 36969b94acceSBarry Smith @*/ 36977087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 36989b94acceSBarry Smith { 36993a40ed3dSBarry Smith PetscFunctionBegin; 37000700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37014482741eSBarry Smith PetscValidPointer(x,2); 370285385478SLisandro Dalcin *x = snes->vec_sol_update; 37033a40ed3dSBarry Smith PetscFunctionReturn(0); 37049b94acceSBarry Smith } 37059b94acceSBarry Smith 37064a2ae208SSatish Balay #undef __FUNCT__ 37074a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 37089b94acceSBarry Smith /*@C 37093638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 37109b94acceSBarry Smith 3711a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 3712c7afd0dbSLois Curfman McInnes 37139b94acceSBarry Smith Input Parameter: 37149b94acceSBarry Smith . snes - the SNES context 37159b94acceSBarry Smith 37169b94acceSBarry Smith Output Parameter: 37177bf4e008SBarry Smith + r - the function (or PETSC_NULL) 371870e92668SMatthew Knepley . func - the function (or PETSC_NULL) 371970e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 37209b94acceSBarry Smith 372136851e7fSLois Curfman McInnes Level: advanced 372236851e7fSLois Curfman McInnes 3723a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 37249b94acceSBarry Smith 37254b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 37269b94acceSBarry Smith @*/ 37277087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 37289b94acceSBarry Smith { 3729a63bb30eSJed Brown PetscErrorCode ierr; 37306cab3a1bSJed Brown DM dm; 3731a63bb30eSJed Brown 37323a40ed3dSBarry Smith PetscFunctionBegin; 37330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3734a63bb30eSJed Brown if (r) { 3735a63bb30eSJed Brown if (!snes->vec_func) { 3736a63bb30eSJed Brown if (snes->vec_rhs) { 3737a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 3738a63bb30eSJed Brown } else if (snes->vec_sol) { 3739a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 3740a63bb30eSJed Brown } else if (snes->dm) { 3741a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 3742a63bb30eSJed Brown } 3743a63bb30eSJed Brown } 3744a63bb30eSJed Brown *r = snes->vec_func; 3745a63bb30eSJed Brown } 37466cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 37476cab3a1bSJed Brown ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr); 37483a40ed3dSBarry Smith PetscFunctionReturn(0); 37499b94acceSBarry Smith } 37509b94acceSBarry Smith 3751c79ef259SPeter Brune /*@C 3752c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3753c79ef259SPeter Brune 3754c79ef259SPeter Brune Input Parameter: 3755c79ef259SPeter Brune . snes - the SNES context 3756c79ef259SPeter Brune 3757c79ef259SPeter Brune Output Parameter: 3758c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3759c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3760c79ef259SPeter Brune 3761c79ef259SPeter Brune Level: advanced 3762c79ef259SPeter Brune 3763c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3764c79ef259SPeter Brune 3765c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3766c79ef259SPeter Brune @*/ 3767c79ef259SPeter Brune 37684a2ae208SSatish Balay #undef __FUNCT__ 3769646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3770646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3771646217ecSPeter Brune { 37726cab3a1bSJed Brown PetscErrorCode ierr; 37736cab3a1bSJed Brown DM dm; 37746cab3a1bSJed Brown 3775646217ecSPeter Brune PetscFunctionBegin; 3776646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37776cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 37786cab3a1bSJed Brown ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr); 3779646217ecSPeter Brune PetscFunctionReturn(0); 3780646217ecSPeter Brune } 3781646217ecSPeter Brune 37824a2ae208SSatish Balay #undef __FUNCT__ 37834a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 37843c7409f5SSatish Balay /*@C 37853c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3786d850072dSLois Curfman McInnes SNES options in the database. 37873c7409f5SSatish Balay 37883f9fe445SBarry Smith Logically Collective on SNES 3789fee21e36SBarry Smith 3790c7afd0dbSLois Curfman McInnes Input Parameter: 3791c7afd0dbSLois Curfman McInnes + snes - the SNES context 3792c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3793c7afd0dbSLois Curfman McInnes 3794d850072dSLois Curfman McInnes Notes: 3795a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3796c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3797d850072dSLois Curfman McInnes 379836851e7fSLois Curfman McInnes Level: advanced 379936851e7fSLois Curfman McInnes 38003c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3801a86d99e1SLois Curfman McInnes 3802a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 38033c7409f5SSatish Balay @*/ 38047087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 38053c7409f5SSatish Balay { 3806dfbe8321SBarry Smith PetscErrorCode ierr; 38073c7409f5SSatish Balay 38083a40ed3dSBarry Smith PetscFunctionBegin; 38090700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3810639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 38111cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 381294b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 38133a40ed3dSBarry Smith PetscFunctionReturn(0); 38143c7409f5SSatish Balay } 38153c7409f5SSatish Balay 38164a2ae208SSatish Balay #undef __FUNCT__ 38174a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 38183c7409f5SSatish Balay /*@C 3819f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3820d850072dSLois Curfman McInnes SNES options in the database. 38213c7409f5SSatish Balay 38223f9fe445SBarry Smith Logically Collective on SNES 3823fee21e36SBarry Smith 3824c7afd0dbSLois Curfman McInnes Input Parameters: 3825c7afd0dbSLois Curfman McInnes + snes - the SNES context 3826c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3827c7afd0dbSLois Curfman McInnes 3828d850072dSLois Curfman McInnes Notes: 3829a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3830c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3831d850072dSLois Curfman McInnes 383236851e7fSLois Curfman McInnes Level: advanced 383336851e7fSLois Curfman McInnes 38343c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3835a86d99e1SLois Curfman McInnes 3836a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 38373c7409f5SSatish Balay @*/ 38387087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 38393c7409f5SSatish Balay { 3840dfbe8321SBarry Smith PetscErrorCode ierr; 38413c7409f5SSatish Balay 38423a40ed3dSBarry Smith PetscFunctionBegin; 38430700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3844639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 38451cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 384694b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 38473a40ed3dSBarry Smith PetscFunctionReturn(0); 38483c7409f5SSatish Balay } 38493c7409f5SSatish Balay 38504a2ae208SSatish Balay #undef __FUNCT__ 38514a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 38529ab63eb5SSatish Balay /*@C 38533c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 38543c7409f5SSatish Balay SNES options in the database. 38553c7409f5SSatish Balay 3856c7afd0dbSLois Curfman McInnes Not Collective 3857c7afd0dbSLois Curfman McInnes 38583c7409f5SSatish Balay Input Parameter: 38593c7409f5SSatish Balay . snes - the SNES context 38603c7409f5SSatish Balay 38613c7409f5SSatish Balay Output Parameter: 38623c7409f5SSatish Balay . prefix - pointer to the prefix string used 38633c7409f5SSatish Balay 38644ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 38659ab63eb5SSatish Balay sufficient length to hold the prefix. 38669ab63eb5SSatish Balay 386736851e7fSLois Curfman McInnes Level: advanced 386836851e7fSLois Curfman McInnes 38693c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 3870a86d99e1SLois Curfman McInnes 3871a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 38723c7409f5SSatish Balay @*/ 38737087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 38743c7409f5SSatish Balay { 3875dfbe8321SBarry Smith PetscErrorCode ierr; 38763c7409f5SSatish Balay 38773a40ed3dSBarry Smith PetscFunctionBegin; 38780700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3879639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 38803a40ed3dSBarry Smith PetscFunctionReturn(0); 38813c7409f5SSatish Balay } 38823c7409f5SSatish Balay 3883b2002411SLois Curfman McInnes 38844a2ae208SSatish Balay #undef __FUNCT__ 38854a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 38863cea93caSBarry Smith /*@C 38873cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 38883cea93caSBarry Smith 38897f6c08e0SMatthew Knepley Level: advanced 38903cea93caSBarry Smith @*/ 38917087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3892b2002411SLois Curfman McInnes { 3893e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3894dfbe8321SBarry Smith PetscErrorCode ierr; 3895b2002411SLois Curfman McInnes 3896b2002411SLois Curfman McInnes PetscFunctionBegin; 3897b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3898c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3899b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3900b2002411SLois Curfman McInnes } 3901da9b6338SBarry Smith 3902da9b6338SBarry Smith #undef __FUNCT__ 3903da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 39047087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3905da9b6338SBarry Smith { 3906dfbe8321SBarry Smith PetscErrorCode ierr; 390777431f27SBarry Smith PetscInt N,i,j; 3908da9b6338SBarry Smith Vec u,uh,fh; 3909da9b6338SBarry Smith PetscScalar value; 3910da9b6338SBarry Smith PetscReal norm; 3911da9b6338SBarry Smith 3912da9b6338SBarry Smith PetscFunctionBegin; 3913da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3914da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3915da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3916da9b6338SBarry Smith 3917da9b6338SBarry Smith /* currently only works for sequential */ 3918da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3919da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3920da9b6338SBarry Smith for (i=0; i<N; i++) { 3921da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 392277431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3923da9b6338SBarry Smith for (j=-10; j<11; j++) { 3924ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3925da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 39263ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3927da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 392877431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3929da9b6338SBarry Smith value = -value; 3930da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3931da9b6338SBarry Smith } 3932da9b6338SBarry Smith } 39336bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 39346bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 3935da9b6338SBarry Smith PetscFunctionReturn(0); 3936da9b6338SBarry Smith } 393771f87433Sdalcinl 393871f87433Sdalcinl #undef __FUNCT__ 3939fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 394071f87433Sdalcinl /*@ 3941fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 394271f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 394371f87433Sdalcinl Newton method. 394471f87433Sdalcinl 39453f9fe445SBarry Smith Logically Collective on SNES 394671f87433Sdalcinl 394771f87433Sdalcinl Input Parameters: 394871f87433Sdalcinl + snes - SNES context 394971f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 395071f87433Sdalcinl 395164ba62caSBarry Smith Options Database: 395264ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 395364ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 395464ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 395564ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 395664ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 395764ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 395864ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 395964ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 396064ba62caSBarry Smith 396171f87433Sdalcinl Notes: 396271f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 396371f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 396471f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 396571f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 396671f87433Sdalcinl solver. 396771f87433Sdalcinl 396871f87433Sdalcinl Level: advanced 396971f87433Sdalcinl 397071f87433Sdalcinl Reference: 397171f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 397271f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 397371f87433Sdalcinl 397471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 397571f87433Sdalcinl 3976fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 397771f87433Sdalcinl @*/ 39787087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 397971f87433Sdalcinl { 398071f87433Sdalcinl PetscFunctionBegin; 39810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3982acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 398371f87433Sdalcinl snes->ksp_ewconv = flag; 398471f87433Sdalcinl PetscFunctionReturn(0); 398571f87433Sdalcinl } 398671f87433Sdalcinl 398771f87433Sdalcinl #undef __FUNCT__ 3988fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 398971f87433Sdalcinl /*@ 3990fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 399171f87433Sdalcinl for computing relative tolerance for linear solvers within an 399271f87433Sdalcinl inexact Newton method. 399371f87433Sdalcinl 399471f87433Sdalcinl Not Collective 399571f87433Sdalcinl 399671f87433Sdalcinl Input Parameter: 399771f87433Sdalcinl . snes - SNES context 399871f87433Sdalcinl 399971f87433Sdalcinl Output Parameter: 400071f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 400171f87433Sdalcinl 400271f87433Sdalcinl Notes: 400371f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 400471f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 400571f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 400671f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 400771f87433Sdalcinl solver. 400871f87433Sdalcinl 400971f87433Sdalcinl Level: advanced 401071f87433Sdalcinl 401171f87433Sdalcinl Reference: 401271f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 401371f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 401471f87433Sdalcinl 401571f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 401671f87433Sdalcinl 4017fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 401871f87433Sdalcinl @*/ 40197087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 402071f87433Sdalcinl { 402171f87433Sdalcinl PetscFunctionBegin; 40220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 402371f87433Sdalcinl PetscValidPointer(flag,2); 402471f87433Sdalcinl *flag = snes->ksp_ewconv; 402571f87433Sdalcinl PetscFunctionReturn(0); 402671f87433Sdalcinl } 402771f87433Sdalcinl 402871f87433Sdalcinl #undef __FUNCT__ 4029fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 403071f87433Sdalcinl /*@ 4031fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 403271f87433Sdalcinl convergence criteria for the linear solvers within an inexact 403371f87433Sdalcinl Newton method. 403471f87433Sdalcinl 40353f9fe445SBarry Smith Logically Collective on SNES 403671f87433Sdalcinl 403771f87433Sdalcinl Input Parameters: 403871f87433Sdalcinl + snes - SNES context 403971f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 404071f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 404171f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 404271f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 404371f87433Sdalcinl (0 <= gamma2 <= 1) 404471f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 404571f87433Sdalcinl . alpha2 - power for safeguard 404671f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 404771f87433Sdalcinl 404871f87433Sdalcinl Note: 404971f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 405071f87433Sdalcinl 405171f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 405271f87433Sdalcinl 405371f87433Sdalcinl Level: advanced 405471f87433Sdalcinl 405571f87433Sdalcinl Reference: 405671f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 405771f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 405871f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 405971f87433Sdalcinl 406071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 406171f87433Sdalcinl 4062fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 406371f87433Sdalcinl @*/ 40647087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 406571f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 406671f87433Sdalcinl { 4067fa9f3622SBarry Smith SNESKSPEW *kctx; 406871f87433Sdalcinl PetscFunctionBegin; 40690700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4070fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4071e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 4072c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 4073c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 4074c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 4075c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 4076c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 4077c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 4078c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 407971f87433Sdalcinl 408071f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 408171f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 408271f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 408371f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 408471f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 408571f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 408671f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 408771f87433Sdalcinl 408871f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 4089e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 409071f87433Sdalcinl } 409171f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 4092e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 409371f87433Sdalcinl } 409471f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 4095e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 409671f87433Sdalcinl } 409771f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 4098e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 409971f87433Sdalcinl } 410071f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 4101e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 410271f87433Sdalcinl } 410371f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 4104e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 410571f87433Sdalcinl } 410671f87433Sdalcinl PetscFunctionReturn(0); 410771f87433Sdalcinl } 410871f87433Sdalcinl 410971f87433Sdalcinl #undef __FUNCT__ 4110fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 411171f87433Sdalcinl /*@ 4112fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 411371f87433Sdalcinl convergence criteria for the linear solvers within an inexact 411471f87433Sdalcinl Newton method. 411571f87433Sdalcinl 411671f87433Sdalcinl Not Collective 411771f87433Sdalcinl 411871f87433Sdalcinl Input Parameters: 411971f87433Sdalcinl snes - SNES context 412071f87433Sdalcinl 412171f87433Sdalcinl Output Parameters: 412271f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 412371f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 412471f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 412571f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 412671f87433Sdalcinl (0 <= gamma2 <= 1) 412771f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 412871f87433Sdalcinl . alpha2 - power for safeguard 412971f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 413071f87433Sdalcinl 413171f87433Sdalcinl Level: advanced 413271f87433Sdalcinl 413371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 413471f87433Sdalcinl 4135fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 413671f87433Sdalcinl @*/ 41377087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 413871f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 413971f87433Sdalcinl { 4140fa9f3622SBarry Smith SNESKSPEW *kctx; 414171f87433Sdalcinl PetscFunctionBegin; 41420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4143fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4144e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 414571f87433Sdalcinl if(version) *version = kctx->version; 414671f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 414771f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 414871f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 414971f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 415071f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 415171f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 415271f87433Sdalcinl PetscFunctionReturn(0); 415371f87433Sdalcinl } 415471f87433Sdalcinl 415571f87433Sdalcinl #undef __FUNCT__ 4156fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 4157fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 415871f87433Sdalcinl { 415971f87433Sdalcinl PetscErrorCode ierr; 4160fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 416171f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 416271f87433Sdalcinl 416371f87433Sdalcinl PetscFunctionBegin; 4164e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 416571f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 416671f87433Sdalcinl rtol = kctx->rtol_0; 416771f87433Sdalcinl } else { 416871f87433Sdalcinl if (kctx->version == 1) { 416971f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 417071f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 417171f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 417271f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 417371f87433Sdalcinl } else if (kctx->version == 2) { 417471f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 417571f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 417671f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 417771f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 417871f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 417971f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 418071f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 418171f87433Sdalcinl stol = PetscMax(rtol,stol); 418271f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 418371f87433Sdalcinl /* safeguard: avoid oversolving */ 418471f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 418571f87433Sdalcinl stol = PetscMax(rtol,stol); 418671f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 4187e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 418871f87433Sdalcinl } 418971f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 419071f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 419171f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 419271f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 419371f87433Sdalcinl PetscFunctionReturn(0); 419471f87433Sdalcinl } 419571f87433Sdalcinl 419671f87433Sdalcinl #undef __FUNCT__ 4197fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 4198fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 419971f87433Sdalcinl { 420071f87433Sdalcinl PetscErrorCode ierr; 4201fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 420271f87433Sdalcinl PCSide pcside; 420371f87433Sdalcinl Vec lres; 420471f87433Sdalcinl 420571f87433Sdalcinl PetscFunctionBegin; 4206e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 420771f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 420871f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 420971f87433Sdalcinl if (kctx->version == 1) { 4210b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 421171f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 421271f87433Sdalcinl /* KSP residual is true linear residual */ 421371f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 421471f87433Sdalcinl } else { 421571f87433Sdalcinl /* KSP residual is preconditioned residual */ 421671f87433Sdalcinl /* compute true linear residual norm */ 421771f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 421871f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 421971f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 422071f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 42216bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 422271f87433Sdalcinl } 422371f87433Sdalcinl } 422471f87433Sdalcinl PetscFunctionReturn(0); 422571f87433Sdalcinl } 422671f87433Sdalcinl 422771f87433Sdalcinl #undef __FUNCT__ 422871f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 422971f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 423071f87433Sdalcinl { 423171f87433Sdalcinl PetscErrorCode ierr; 423271f87433Sdalcinl 423371f87433Sdalcinl PetscFunctionBegin; 4234fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 423571f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 4236fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 423771f87433Sdalcinl PetscFunctionReturn(0); 423871f87433Sdalcinl } 42396c699258SBarry Smith 42406c699258SBarry Smith #undef __FUNCT__ 42416c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 42426c699258SBarry Smith /*@ 42436c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 42446c699258SBarry Smith 42453f9fe445SBarry Smith Logically Collective on SNES 42466c699258SBarry Smith 42476c699258SBarry Smith Input Parameters: 42486c699258SBarry Smith + snes - the preconditioner context 42496c699258SBarry Smith - dm - the dm 42506c699258SBarry Smith 42516c699258SBarry Smith Level: intermediate 42526c699258SBarry Smith 42536c699258SBarry Smith 42546c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 42556c699258SBarry Smith @*/ 42567087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 42576c699258SBarry Smith { 42586c699258SBarry Smith PetscErrorCode ierr; 4259345fed2cSBarry Smith KSP ksp; 42606cab3a1bSJed Brown SNESDM sdm; 42616c699258SBarry Smith 42626c699258SBarry Smith PetscFunctionBegin; 42630700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4264d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 42656cab3a1bSJed Brown if (snes->dm) { /* Move the SNESDM context over to the new DM unless the new DM already has one */ 42666cab3a1bSJed Brown PetscContainer oldcontainer,container; 42676cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 42686cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr); 42696cab3a1bSJed Brown if (oldcontainer && !container) { 42706cab3a1bSJed Brown ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr); 42716cab3a1bSJed Brown ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr); 42726cab3a1bSJed Brown if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */ 42736cab3a1bSJed Brown sdm->originaldm = dm; 42746cab3a1bSJed Brown } 42756cab3a1bSJed Brown } 42766bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 42776cab3a1bSJed Brown } 42786c699258SBarry Smith snes->dm = dm; 4279345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4280345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4281f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 42822c155ee1SBarry Smith if (snes->pc) { 42832c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 42842c155ee1SBarry Smith } 42856c699258SBarry Smith PetscFunctionReturn(0); 42866c699258SBarry Smith } 42876c699258SBarry Smith 42886c699258SBarry Smith #undef __FUNCT__ 42896c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 42906c699258SBarry Smith /*@ 42916c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 42926c699258SBarry Smith 42933f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 42946c699258SBarry Smith 42956c699258SBarry Smith Input Parameter: 42966c699258SBarry Smith . snes - the preconditioner context 42976c699258SBarry Smith 42986c699258SBarry Smith Output Parameter: 42996c699258SBarry Smith . dm - the dm 43006c699258SBarry Smith 43016c699258SBarry Smith Level: intermediate 43026c699258SBarry Smith 43036c699258SBarry Smith 43046c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 43056c699258SBarry Smith @*/ 43067087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 43076c699258SBarry Smith { 43086cab3a1bSJed Brown PetscErrorCode ierr; 43096cab3a1bSJed Brown 43106c699258SBarry Smith PetscFunctionBegin; 43110700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 43126cab3a1bSJed Brown if (!snes->dm) { 43136cab3a1bSJed Brown ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr); 43146cab3a1bSJed Brown } 43156c699258SBarry Smith *dm = snes->dm; 43166c699258SBarry Smith PetscFunctionReturn(0); 43176c699258SBarry Smith } 43180807856dSBarry Smith 431931823bd8SMatthew G Knepley #undef __FUNCT__ 432031823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 432131823bd8SMatthew G Knepley /*@ 4322fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 432331823bd8SMatthew G Knepley 432431823bd8SMatthew G Knepley Collective on SNES 432531823bd8SMatthew G Knepley 432631823bd8SMatthew G Knepley Input Parameters: 432731823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 432831823bd8SMatthew G Knepley - pc - the preconditioner object 432931823bd8SMatthew G Knepley 433031823bd8SMatthew G Knepley Notes: 433131823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 433231823bd8SMatthew G Knepley to configure it using the API). 433331823bd8SMatthew G Knepley 433431823bd8SMatthew G Knepley Level: developer 433531823bd8SMatthew G Knepley 433631823bd8SMatthew G Knepley .keywords: SNES, set, precondition 433731823bd8SMatthew G Knepley .seealso: SNESGetPC() 433831823bd8SMatthew G Knepley @*/ 433931823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 434031823bd8SMatthew G Knepley { 434131823bd8SMatthew G Knepley PetscErrorCode ierr; 434231823bd8SMatthew G Knepley 434331823bd8SMatthew G Knepley PetscFunctionBegin; 434431823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 434531823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 434631823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 434731823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4348bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 434931823bd8SMatthew G Knepley snes->pc = pc; 435031823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 435131823bd8SMatthew G Knepley PetscFunctionReturn(0); 435231823bd8SMatthew G Knepley } 435331823bd8SMatthew G Knepley 435431823bd8SMatthew G Knepley #undef __FUNCT__ 435531823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 435631823bd8SMatthew G Knepley /*@ 4357fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 435831823bd8SMatthew G Knepley 435931823bd8SMatthew G Knepley Not Collective 436031823bd8SMatthew G Knepley 436131823bd8SMatthew G Knepley Input Parameter: 436231823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 436331823bd8SMatthew G Knepley 436431823bd8SMatthew G Knepley Output Parameter: 436531823bd8SMatthew G Knepley . pc - preconditioner context 436631823bd8SMatthew G Knepley 436731823bd8SMatthew G Knepley Level: developer 436831823bd8SMatthew G Knepley 436931823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 437031823bd8SMatthew G Knepley .seealso: SNESSetPC() 437131823bd8SMatthew G Knepley @*/ 437231823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 437331823bd8SMatthew G Knepley { 437431823bd8SMatthew G Knepley PetscErrorCode ierr; 437531823bd8SMatthew G Knepley 437631823bd8SMatthew G Knepley PetscFunctionBegin; 437731823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 437831823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 437931823bd8SMatthew G Knepley if (!snes->pc) { 438031823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr); 43814a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr); 438231823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 438331823bd8SMatthew G Knepley } 438431823bd8SMatthew G Knepley *pc = snes->pc; 438531823bd8SMatthew G Knepley PetscFunctionReturn(0); 438631823bd8SMatthew G Knepley } 438731823bd8SMatthew G Knepley 43889e764e56SPeter Brune #undef __FUNCT__ 4389f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch" 43909e764e56SPeter Brune /*@ 4391f1c6b773SPeter Brune SNESSetSNESLineSearch - Sets the linesearch. 43929e764e56SPeter Brune 43939e764e56SPeter Brune Collective on SNES 43949e764e56SPeter Brune 43959e764e56SPeter Brune Input Parameters: 43969e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 43979e764e56SPeter Brune - linesearch - the linesearch object 43989e764e56SPeter Brune 43999e764e56SPeter Brune Notes: 4400f1c6b773SPeter Brune Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example, 44019e764e56SPeter Brune to configure it using the API). 44029e764e56SPeter Brune 44039e764e56SPeter Brune Level: developer 44049e764e56SPeter Brune 44059e764e56SPeter Brune .keywords: SNES, set, linesearch 4406f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch() 44079e764e56SPeter Brune @*/ 4408f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch) 44099e764e56SPeter Brune { 44109e764e56SPeter Brune PetscErrorCode ierr; 44119e764e56SPeter Brune 44129e764e56SPeter Brune PetscFunctionBegin; 44139e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4414f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 44159e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 44169e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 4417f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 44189e764e56SPeter Brune snes->linesearch = linesearch; 44199e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 44209e764e56SPeter Brune PetscFunctionReturn(0); 44219e764e56SPeter Brune } 44229e764e56SPeter Brune 44239e764e56SPeter Brune #undef __FUNCT__ 4424f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch" 4425ea5d4fccSPeter Brune /*@C 4426f1c6b773SPeter Brune SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch(). 44279e764e56SPeter Brune 44289e764e56SPeter Brune Not Collective 44299e764e56SPeter Brune 44309e764e56SPeter Brune Input Parameter: 44319e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 44329e764e56SPeter Brune 44339e764e56SPeter Brune Output Parameter: 44349e764e56SPeter Brune . linesearch - linesearch context 44359e764e56SPeter Brune 44369e764e56SPeter Brune Level: developer 44379e764e56SPeter Brune 44389e764e56SPeter Brune .keywords: SNES, get, linesearch 4439f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch() 44409e764e56SPeter Brune @*/ 4441f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch) 44429e764e56SPeter Brune { 44439e764e56SPeter Brune PetscErrorCode ierr; 44449e764e56SPeter Brune const char *optionsprefix; 44459e764e56SPeter Brune 44469e764e56SPeter Brune PetscFunctionBegin; 44479e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 44489e764e56SPeter Brune PetscValidPointer(linesearch, 2); 44499e764e56SPeter Brune if (!snes->linesearch) { 44509e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 4451f1c6b773SPeter Brune ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr); 4452f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 4453b1dca40bSPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 44549e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 44559e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 44569e764e56SPeter Brune } 44579e764e56SPeter Brune *linesearch = snes->linesearch; 44589e764e56SPeter Brune PetscFunctionReturn(0); 44599e764e56SPeter Brune } 44609e764e56SPeter Brune 446169b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4462c6db04a5SJed Brown #include <mex.h> 446369b4f73cSBarry Smith 44648f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 44658f6e6473SBarry Smith 44660807856dSBarry Smith #undef __FUNCT__ 44670807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 44680807856dSBarry Smith /* 44690807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 44700807856dSBarry Smith SNESSetFunctionMatlab(). 44710807856dSBarry Smith 44720807856dSBarry Smith Collective on SNES 44730807856dSBarry Smith 44740807856dSBarry Smith Input Parameters: 44750807856dSBarry Smith + snes - the SNES context 44760807856dSBarry Smith - x - input vector 44770807856dSBarry Smith 44780807856dSBarry Smith Output Parameter: 44790807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 44800807856dSBarry Smith 44810807856dSBarry Smith Notes: 44820807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 44830807856dSBarry Smith implementations, so most users would not generally call this routine 44840807856dSBarry Smith themselves. 44850807856dSBarry Smith 44860807856dSBarry Smith Level: developer 44870807856dSBarry Smith 44880807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 44890807856dSBarry Smith 44900807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 449161b2408cSBarry Smith */ 44927087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 44930807856dSBarry Smith { 4494e650e774SBarry Smith PetscErrorCode ierr; 44958f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 44968f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 44978f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 449891621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 4499e650e774SBarry Smith 45000807856dSBarry Smith PetscFunctionBegin; 45010807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 45020807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 45030807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 45040807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 45050807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 45060807856dSBarry Smith 45070807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 4508e650e774SBarry Smith 450991621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4510e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4511e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 451291621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 451391621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 451491621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 45158f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 45168f6e6473SBarry Smith prhs[4] = sctx->ctx; 4517b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 4518e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4519e650e774SBarry Smith mxDestroyArray(prhs[0]); 4520e650e774SBarry Smith mxDestroyArray(prhs[1]); 4521e650e774SBarry Smith mxDestroyArray(prhs[2]); 45228f6e6473SBarry Smith mxDestroyArray(prhs[3]); 4523e650e774SBarry Smith mxDestroyArray(plhs[0]); 45240807856dSBarry Smith PetscFunctionReturn(0); 45250807856dSBarry Smith } 45260807856dSBarry Smith 45270807856dSBarry Smith 45280807856dSBarry Smith #undef __FUNCT__ 45290807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 453061b2408cSBarry Smith /* 45310807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 45320807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4533e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 45340807856dSBarry Smith 45350807856dSBarry Smith Logically Collective on SNES 45360807856dSBarry Smith 45370807856dSBarry Smith Input Parameters: 45380807856dSBarry Smith + snes - the SNES context 45390807856dSBarry Smith . r - vector to store function value 45400807856dSBarry Smith - func - function evaluation routine 45410807856dSBarry Smith 45420807856dSBarry Smith Calling sequence of func: 454361b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 45440807856dSBarry Smith 45450807856dSBarry Smith 45460807856dSBarry Smith Notes: 45470807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 45480807856dSBarry Smith $ f'(x) x = -f(x), 45490807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 45500807856dSBarry Smith 45510807856dSBarry Smith Level: beginner 45520807856dSBarry Smith 45530807856dSBarry Smith .keywords: SNES, nonlinear, set, function 45540807856dSBarry Smith 45550807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 455661b2408cSBarry Smith */ 45577087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 45580807856dSBarry Smith { 45590807856dSBarry Smith PetscErrorCode ierr; 45608f6e6473SBarry Smith SNESMatlabContext *sctx; 45610807856dSBarry Smith 45620807856dSBarry Smith PetscFunctionBegin; 45638f6e6473SBarry Smith /* currently sctx is memory bleed */ 45648f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 45658f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 45668f6e6473SBarry Smith /* 45678f6e6473SBarry Smith This should work, but it doesn't 45688f6e6473SBarry Smith sctx->ctx = ctx; 45698f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 45708f6e6473SBarry Smith */ 45718f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 45728f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 45730807856dSBarry Smith PetscFunctionReturn(0); 45740807856dSBarry Smith } 457569b4f73cSBarry Smith 457661b2408cSBarry Smith #undef __FUNCT__ 457761b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 457861b2408cSBarry Smith /* 457961b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 458061b2408cSBarry Smith SNESSetJacobianMatlab(). 458161b2408cSBarry Smith 458261b2408cSBarry Smith Collective on SNES 458361b2408cSBarry Smith 458461b2408cSBarry Smith Input Parameters: 458561b2408cSBarry Smith + snes - the SNES context 458661b2408cSBarry Smith . x - input vector 458761b2408cSBarry Smith . A, B - the matrices 458861b2408cSBarry Smith - ctx - user context 458961b2408cSBarry Smith 459061b2408cSBarry Smith Output Parameter: 459161b2408cSBarry Smith . flag - structure of the matrix 459261b2408cSBarry Smith 459361b2408cSBarry Smith Level: developer 459461b2408cSBarry Smith 459561b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 459661b2408cSBarry Smith 459761b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 459861b2408cSBarry Smith @*/ 45997087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 460061b2408cSBarry Smith { 460161b2408cSBarry Smith PetscErrorCode ierr; 460261b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 460361b2408cSBarry Smith int nlhs = 2,nrhs = 6; 460461b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 460561b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 460661b2408cSBarry Smith 460761b2408cSBarry Smith PetscFunctionBegin; 460861b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 460961b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 461061b2408cSBarry Smith 461161b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 461261b2408cSBarry Smith 461361b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 461461b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 461561b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 461661b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 461761b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 461861b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 461961b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 462061b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 462161b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 462261b2408cSBarry Smith prhs[5] = sctx->ctx; 4623b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 462461b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 462561b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 462661b2408cSBarry Smith mxDestroyArray(prhs[0]); 462761b2408cSBarry Smith mxDestroyArray(prhs[1]); 462861b2408cSBarry Smith mxDestroyArray(prhs[2]); 462961b2408cSBarry Smith mxDestroyArray(prhs[3]); 463061b2408cSBarry Smith mxDestroyArray(prhs[4]); 463161b2408cSBarry Smith mxDestroyArray(plhs[0]); 463261b2408cSBarry Smith mxDestroyArray(plhs[1]); 463361b2408cSBarry Smith PetscFunctionReturn(0); 463461b2408cSBarry Smith } 463561b2408cSBarry Smith 463661b2408cSBarry Smith 463761b2408cSBarry Smith #undef __FUNCT__ 463861b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 463961b2408cSBarry Smith /* 464061b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 464161b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4642e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 464361b2408cSBarry Smith 464461b2408cSBarry Smith Logically Collective on SNES 464561b2408cSBarry Smith 464661b2408cSBarry Smith Input Parameters: 464761b2408cSBarry Smith + snes - the SNES context 464861b2408cSBarry Smith . A,B - Jacobian matrices 464961b2408cSBarry Smith . func - function evaluation routine 465061b2408cSBarry Smith - ctx - user context 465161b2408cSBarry Smith 465261b2408cSBarry Smith Calling sequence of func: 465361b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 465461b2408cSBarry Smith 465561b2408cSBarry Smith 465661b2408cSBarry Smith Level: developer 465761b2408cSBarry Smith 465861b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 465961b2408cSBarry Smith 466061b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 466161b2408cSBarry Smith */ 46627087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 466361b2408cSBarry Smith { 466461b2408cSBarry Smith PetscErrorCode ierr; 466561b2408cSBarry Smith SNESMatlabContext *sctx; 466661b2408cSBarry Smith 466761b2408cSBarry Smith PetscFunctionBegin; 466861b2408cSBarry Smith /* currently sctx is memory bleed */ 466961b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 467061b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 467161b2408cSBarry Smith /* 467261b2408cSBarry Smith This should work, but it doesn't 467361b2408cSBarry Smith sctx->ctx = ctx; 467461b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 467561b2408cSBarry Smith */ 467661b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 467761b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 467861b2408cSBarry Smith PetscFunctionReturn(0); 467961b2408cSBarry Smith } 468069b4f73cSBarry Smith 4681f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4682f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4683f9eb7ae2SShri Abhyankar /* 4684f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4685f9eb7ae2SShri Abhyankar 4686f9eb7ae2SShri Abhyankar Collective on SNES 4687f9eb7ae2SShri Abhyankar 4688f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4689f9eb7ae2SShri Abhyankar @*/ 46907087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4691f9eb7ae2SShri Abhyankar { 4692f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 469348f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4694f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4695f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4696f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4697f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4698f9eb7ae2SShri Abhyankar 4699f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4700f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4701f9eb7ae2SShri Abhyankar 4702f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4703f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4704f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4705f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4706f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4707f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4708f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4709f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4710f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4711f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4712f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4713f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4714f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4715f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4716f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4717f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4718f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4719f9eb7ae2SShri Abhyankar } 4720f9eb7ae2SShri Abhyankar 4721f9eb7ae2SShri Abhyankar 4722f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4723f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4724f9eb7ae2SShri Abhyankar /* 4725e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4726f9eb7ae2SShri Abhyankar 4727f9eb7ae2SShri Abhyankar Level: developer 4728f9eb7ae2SShri Abhyankar 4729f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4730f9eb7ae2SShri Abhyankar 4731f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4732f9eb7ae2SShri Abhyankar */ 47337087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4734f9eb7ae2SShri Abhyankar { 4735f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4736f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4737f9eb7ae2SShri Abhyankar 4738f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4739f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4740f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4741f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4742f9eb7ae2SShri Abhyankar /* 4743f9eb7ae2SShri Abhyankar This should work, but it doesn't 4744f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4745f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4746f9eb7ae2SShri Abhyankar */ 4747f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4748f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4749f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4750f9eb7ae2SShri Abhyankar } 4751f9eb7ae2SShri Abhyankar 475269b4f73cSBarry Smith #endif 4753