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 584fdacfa88SPeter Brune ierr = PetscOptionsEList("-snes_norm_type","SNES Norm type","SNESSetNormType",SNESNormTypes,5,"function",&indx,&flg);CHKERRQ(ierr); 585fdacfa88SPeter Brune if (flg) { ierr = SNESSetNormType(snes,(SNESNormType)indx);CHKERRQ(ierr); } 586fdacfa88SPeter Brune 58785385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 58885385478SLisandro Dalcin 589acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 590186905e3SBarry Smith 591fa9f3622SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 592fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 593fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 594fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 595fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 596fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 597fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 598186905e3SBarry Smith 59990d69ab7SBarry Smith flg = PETSC_FALSE; 600acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 601a6570f20SBarry Smith if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 602eabae89aSBarry Smith 603a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 604e8105e01SRichard Katz if (flg) { 605649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 606649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 607e8105e01SRichard Katz } 608eabae89aSBarry Smith 609b271bb04SBarry Smith ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 610b271bb04SBarry Smith if (flg) { 611b271bb04SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 612b271bb04SBarry Smith } 613b271bb04SBarry Smith 614a6570f20SBarry Smith ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 615eabae89aSBarry Smith if (flg) { 616649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 617f1bef1bcSMatthew Knepley ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 618e8105e01SRichard Katz } 619eabae89aSBarry Smith 620a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 621eabae89aSBarry Smith if (flg) { 622649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 623649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 624eabae89aSBarry Smith } 625eabae89aSBarry Smith 6265180491cSLisandro Dalcin ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 6275180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 6285180491cSLisandro Dalcin 62990d69ab7SBarry Smith flg = PETSC_FALSE; 630acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 631a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 63290d69ab7SBarry Smith flg = PETSC_FALSE; 633acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 634a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 63590d69ab7SBarry Smith flg = PETSC_FALSE; 636acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 637a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 63890d69ab7SBarry Smith flg = PETSC_FALSE; 639acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 640a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 64190d69ab7SBarry Smith flg = PETSC_FALSE; 642acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 643b271bb04SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 644e24b481bSBarry Smith 64590d69ab7SBarry Smith flg = PETSC_FALSE; 646acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 6474b27c08aSLois Curfman McInnes if (flg) { 6486cab3a1bSJed Brown void *functx; 6496cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 6506cab3a1bSJed Brown ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr); 651ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 6529b94acceSBarry Smith } 653639f9d9dSBarry Smith 654aa3661deSLisandro Dalcin mf = mf_operator = PETSC_FALSE; 655aa3661deSLisandro Dalcin flg = PETSC_FALSE; 656acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr); 657a8248277SBarry Smith if (flg && mf_operator) { 658a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 659a8248277SBarry Smith mf = PETSC_TRUE; 660a8248277SBarry Smith } 661aa3661deSLisandro Dalcin flg = PETSC_FALSE; 662acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr); 663aa3661deSLisandro Dalcin if (!flg && mf_operator) mf = PETSC_TRUE; 664aa3661deSLisandro Dalcin mf_version = 1; 665aa3661deSLisandro Dalcin ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr); 666aa3661deSLisandro Dalcin 667d28543b3SPeter Brune 66889b92e6fSPeter Brune /* GS Options */ 66989b92e6fSPeter Brune ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr); 67089b92e6fSPeter Brune 67176b2cf59SMatthew Knepley for(i = 0; i < numberofsetfromoptions; i++) { 67276b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 67376b2cf59SMatthew Knepley } 67476b2cf59SMatthew Knepley 675e7788613SBarry Smith if (snes->ops->setfromoptions) { 676e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 677639f9d9dSBarry Smith } 6785d973c19SBarry Smith 6795d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 6805d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 681b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 6824bbc92c1SBarry Smith 683aa3661deSLisandro Dalcin if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 6841cee3971SBarry Smith 6851cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 686aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 687aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 68885385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 68993993e2dSLois Curfman McInnes 6909e764e56SPeter Brune if (!snes->linesearch) { 691f1c6b773SPeter Brune ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 6929e764e56SPeter Brune } 693f1c6b773SPeter Brune ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr); 6949e764e56SPeter Brune 69551e86f29SPeter Brune /* if someone has set the SNES PC type, create it. */ 69651e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 69751e86f29SPeter Brune ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 69851e86f29SPeter Brune if (pcset && (!snes->pc)) { 69951e86f29SPeter Brune ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr); 70051e86f29SPeter Brune } 7014a0c5b0cSMatthew G Knepley if (snes->pc) { 702fde0ff24SPeter Brune ierr = SNESSetOptionsPrefix(snes->pc, optionsprefix);CHKERRQ(ierr); 703fde0ff24SPeter Brune ierr = SNESAppendOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr); 7044a0c5b0cSMatthew G Knepley ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 70588976e71SPeter Brune /* default to 1 iteration */ 70688976e71SPeter Brune ierr = SNESSetTolerances(snes->pc, snes->pc->abstol, snes->pc->rtol, snes->pc->stol, 1, snes->pc->max_funcs);CHKERRQ(ierr); 707*534ebe21SPeter Brune ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); 7084a0c5b0cSMatthew G Knepley ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 7094a0c5b0cSMatthew G Knepley } 7103a40ed3dSBarry Smith PetscFunctionReturn(0); 7119b94acceSBarry Smith } 7129b94acceSBarry Smith 713d25893d9SBarry Smith #undef __FUNCT__ 714d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 715d25893d9SBarry Smith /*@ 716d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 717d25893d9SBarry Smith the nonlinear solvers. 718d25893d9SBarry Smith 719d25893d9SBarry Smith Logically Collective on SNES 720d25893d9SBarry Smith 721d25893d9SBarry Smith Input Parameters: 722d25893d9SBarry Smith + snes - the SNES context 723d25893d9SBarry Smith . compute - function to compute the context 724d25893d9SBarry Smith - destroy - function to destroy the context 725d25893d9SBarry Smith 726d25893d9SBarry Smith Level: intermediate 727d25893d9SBarry Smith 728d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 729d25893d9SBarry Smith 730d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 731d25893d9SBarry Smith @*/ 732d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 733d25893d9SBarry Smith { 734d25893d9SBarry Smith PetscFunctionBegin; 735d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 736d25893d9SBarry Smith snes->ops->usercompute = compute; 737d25893d9SBarry Smith snes->ops->userdestroy = destroy; 738d25893d9SBarry Smith PetscFunctionReturn(0); 739d25893d9SBarry Smith } 740a847f771SSatish Balay 7414a2ae208SSatish Balay #undef __FUNCT__ 7424a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 743b07ff414SBarry Smith /*@ 7449b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 7459b94acceSBarry Smith the nonlinear solvers. 7469b94acceSBarry Smith 7473f9fe445SBarry Smith Logically Collective on SNES 748fee21e36SBarry Smith 749c7afd0dbSLois Curfman McInnes Input Parameters: 750c7afd0dbSLois Curfman McInnes + snes - the SNES context 751c7afd0dbSLois Curfman McInnes - usrP - optional user context 752c7afd0dbSLois Curfman McInnes 75336851e7fSLois Curfman McInnes Level: intermediate 75436851e7fSLois Curfman McInnes 7559b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 7569b94acceSBarry Smith 757d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext() 7589b94acceSBarry Smith @*/ 7597087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 7609b94acceSBarry Smith { 7611b2093e4SBarry Smith PetscErrorCode ierr; 762b07ff414SBarry Smith KSP ksp; 7631b2093e4SBarry Smith 7643a40ed3dSBarry Smith PetscFunctionBegin; 7650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 766b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 767b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 7689b94acceSBarry Smith snes->user = usrP; 7693a40ed3dSBarry Smith PetscFunctionReturn(0); 7709b94acceSBarry Smith } 77174679c65SBarry Smith 7724a2ae208SSatish Balay #undef __FUNCT__ 7734a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 774b07ff414SBarry Smith /*@ 7759b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 7769b94acceSBarry Smith nonlinear solvers. 7779b94acceSBarry Smith 778c7afd0dbSLois Curfman McInnes Not Collective 779c7afd0dbSLois Curfman McInnes 7809b94acceSBarry Smith Input Parameter: 7819b94acceSBarry Smith . snes - SNES context 7829b94acceSBarry Smith 7839b94acceSBarry Smith Output Parameter: 7849b94acceSBarry Smith . usrP - user context 7859b94acceSBarry Smith 78636851e7fSLois Curfman McInnes Level: intermediate 78736851e7fSLois Curfman McInnes 7889b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 7899b94acceSBarry Smith 7909b94acceSBarry Smith .seealso: SNESSetApplicationContext() 7919b94acceSBarry Smith @*/ 792e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 7939b94acceSBarry Smith { 7943a40ed3dSBarry Smith PetscFunctionBegin; 7950700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 796e71120c6SJed Brown *(void**)usrP = snes->user; 7973a40ed3dSBarry Smith PetscFunctionReturn(0); 7989b94acceSBarry Smith } 79974679c65SBarry Smith 8004a2ae208SSatish Balay #undef __FUNCT__ 8014a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 8029b94acceSBarry Smith /*@ 803c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 804c8228a4eSBarry Smith at this time. 8059b94acceSBarry Smith 806c7afd0dbSLois Curfman McInnes Not Collective 807c7afd0dbSLois Curfman McInnes 8089b94acceSBarry Smith Input Parameter: 8099b94acceSBarry Smith . snes - SNES context 8109b94acceSBarry Smith 8119b94acceSBarry Smith Output Parameter: 8129b94acceSBarry Smith . iter - iteration number 8139b94acceSBarry Smith 814c8228a4eSBarry Smith Notes: 815c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 816c8228a4eSBarry Smith 817c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 81808405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 81908405cd6SLois Curfman McInnes .vb 82008405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 82108405cd6SLois Curfman McInnes if (!(it % 2)) { 82208405cd6SLois Curfman McInnes [compute Jacobian here] 82308405cd6SLois Curfman McInnes } 82408405cd6SLois Curfman McInnes .ve 825c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 82608405cd6SLois Curfman McInnes recomputed every second SNES iteration. 827c8228a4eSBarry Smith 82836851e7fSLois Curfman McInnes Level: intermediate 82936851e7fSLois Curfman McInnes 8302b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 8312b668275SBarry Smith 832b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 8339b94acceSBarry Smith @*/ 8347087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 8359b94acceSBarry Smith { 8363a40ed3dSBarry Smith PetscFunctionBegin; 8370700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8384482741eSBarry Smith PetscValidIntPointer(iter,2); 8399b94acceSBarry Smith *iter = snes->iter; 8403a40ed3dSBarry Smith PetscFunctionReturn(0); 8419b94acceSBarry Smith } 84274679c65SBarry Smith 8434a2ae208SSatish Balay #undef __FUNCT__ 844360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber" 845360c497dSPeter Brune /*@ 846360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 847360c497dSPeter Brune 848360c497dSPeter Brune Not Collective 849360c497dSPeter Brune 850360c497dSPeter Brune Input Parameter: 851360c497dSPeter Brune . snes - SNES context 852360c497dSPeter Brune . iter - iteration number 853360c497dSPeter Brune 854360c497dSPeter Brune Level: developer 855360c497dSPeter Brune 856360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number, 857360c497dSPeter Brune 858360c497dSPeter Brune .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 859360c497dSPeter Brune @*/ 860360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 861360c497dSPeter Brune { 862360c497dSPeter Brune PetscErrorCode ierr; 863360c497dSPeter Brune 864360c497dSPeter Brune PetscFunctionBegin; 865360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 866360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 867360c497dSPeter Brune snes->iter = iter; 868360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 869360c497dSPeter Brune PetscFunctionReturn(0); 870360c497dSPeter Brune } 871360c497dSPeter Brune 872360c497dSPeter Brune #undef __FUNCT__ 8734a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 8749b94acceSBarry Smith /*@ 8759b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 8769b94acceSBarry Smith with SNESSSetFunction(). 8779b94acceSBarry Smith 878c7afd0dbSLois Curfman McInnes Collective on SNES 879c7afd0dbSLois Curfman McInnes 8809b94acceSBarry Smith Input Parameter: 8819b94acceSBarry Smith . snes - SNES context 8829b94acceSBarry Smith 8839b94acceSBarry Smith Output Parameter: 8849b94acceSBarry Smith . fnorm - 2-norm of function 8859b94acceSBarry Smith 88636851e7fSLois Curfman McInnes Level: intermediate 88736851e7fSLois Curfman McInnes 8889b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 889a86d99e1SLois Curfman McInnes 890b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 8919b94acceSBarry Smith @*/ 8927087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 8939b94acceSBarry Smith { 8943a40ed3dSBarry Smith PetscFunctionBegin; 8950700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8964482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 8979b94acceSBarry Smith *fnorm = snes->norm; 8983a40ed3dSBarry Smith PetscFunctionReturn(0); 8999b94acceSBarry Smith } 90074679c65SBarry Smith 901360c497dSPeter Brune 902360c497dSPeter Brune #undef __FUNCT__ 903360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm" 904360c497dSPeter Brune /*@ 905360c497dSPeter Brune SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm(). 906360c497dSPeter Brune 907360c497dSPeter Brune Collective on SNES 908360c497dSPeter Brune 909360c497dSPeter Brune Input Parameter: 910360c497dSPeter Brune . snes - SNES context 911360c497dSPeter Brune . fnorm - 2-norm of function 912360c497dSPeter Brune 913360c497dSPeter Brune Level: developer 914360c497dSPeter Brune 915360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm 916360c497dSPeter Brune 917360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm(). 918360c497dSPeter Brune @*/ 919360c497dSPeter Brune PetscErrorCode SNESSetFunctionNorm(SNES snes,PetscReal fnorm) 920360c497dSPeter Brune { 921360c497dSPeter Brune 922360c497dSPeter Brune PetscErrorCode ierr; 923360c497dSPeter Brune 924360c497dSPeter Brune PetscFunctionBegin; 925360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 926360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 927360c497dSPeter Brune snes->norm = fnorm; 928360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 929360c497dSPeter Brune PetscFunctionReturn(0); 930360c497dSPeter Brune } 931360c497dSPeter Brune 9324a2ae208SSatish Balay #undef __FUNCT__ 933b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 9349b94acceSBarry Smith /*@ 935b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 9369b94acceSBarry Smith attempted by the nonlinear solver. 9379b94acceSBarry Smith 938c7afd0dbSLois Curfman McInnes Not Collective 939c7afd0dbSLois Curfman McInnes 9409b94acceSBarry Smith Input Parameter: 9419b94acceSBarry Smith . snes - SNES context 9429b94acceSBarry Smith 9439b94acceSBarry Smith Output Parameter: 9449b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 9459b94acceSBarry Smith 946c96a6f78SLois Curfman McInnes Notes: 947c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 948c96a6f78SLois Curfman McInnes 94936851e7fSLois Curfman McInnes Level: intermediate 95036851e7fSLois Curfman McInnes 9519b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 95258ebbce7SBarry Smith 953e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 95458ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 9559b94acceSBarry Smith @*/ 9567087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 9579b94acceSBarry Smith { 9583a40ed3dSBarry Smith PetscFunctionBegin; 9590700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9604482741eSBarry Smith PetscValidIntPointer(nfails,2); 96150ffb88aSMatthew Knepley *nfails = snes->numFailures; 96250ffb88aSMatthew Knepley PetscFunctionReturn(0); 96350ffb88aSMatthew Knepley } 96450ffb88aSMatthew Knepley 96550ffb88aSMatthew Knepley #undef __FUNCT__ 966b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 96750ffb88aSMatthew Knepley /*@ 968b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 96950ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 97050ffb88aSMatthew Knepley 97150ffb88aSMatthew Knepley Not Collective 97250ffb88aSMatthew Knepley 97350ffb88aSMatthew Knepley Input Parameters: 97450ffb88aSMatthew Knepley + snes - SNES context 97550ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 97650ffb88aSMatthew Knepley 97750ffb88aSMatthew Knepley Level: intermediate 97850ffb88aSMatthew Knepley 97950ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 98058ebbce7SBarry Smith 981e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 98258ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 98350ffb88aSMatthew Knepley @*/ 9847087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 98550ffb88aSMatthew Knepley { 98650ffb88aSMatthew Knepley PetscFunctionBegin; 9870700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 98850ffb88aSMatthew Knepley snes->maxFailures = maxFails; 98950ffb88aSMatthew Knepley PetscFunctionReturn(0); 99050ffb88aSMatthew Knepley } 99150ffb88aSMatthew Knepley 99250ffb88aSMatthew Knepley #undef __FUNCT__ 993b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 99450ffb88aSMatthew Knepley /*@ 995b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 99650ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 99750ffb88aSMatthew Knepley 99850ffb88aSMatthew Knepley Not Collective 99950ffb88aSMatthew Knepley 100050ffb88aSMatthew Knepley Input Parameter: 100150ffb88aSMatthew Knepley . snes - SNES context 100250ffb88aSMatthew Knepley 100350ffb88aSMatthew Knepley Output Parameter: 100450ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 100550ffb88aSMatthew Knepley 100650ffb88aSMatthew Knepley Level: intermediate 100750ffb88aSMatthew Knepley 100850ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 100958ebbce7SBarry Smith 1010e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 101158ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 101258ebbce7SBarry Smith 101350ffb88aSMatthew Knepley @*/ 10147087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 101550ffb88aSMatthew Knepley { 101650ffb88aSMatthew Knepley PetscFunctionBegin; 10170700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10184482741eSBarry Smith PetscValidIntPointer(maxFails,2); 101950ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 10203a40ed3dSBarry Smith PetscFunctionReturn(0); 10219b94acceSBarry Smith } 1022a847f771SSatish Balay 10234a2ae208SSatish Balay #undef __FUNCT__ 10242541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 10252541af92SBarry Smith /*@ 10262541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 10272541af92SBarry Smith done by SNES. 10282541af92SBarry Smith 10292541af92SBarry Smith Not Collective 10302541af92SBarry Smith 10312541af92SBarry Smith Input Parameter: 10322541af92SBarry Smith . snes - SNES context 10332541af92SBarry Smith 10342541af92SBarry Smith Output Parameter: 10352541af92SBarry Smith . nfuncs - number of evaluations 10362541af92SBarry Smith 10372541af92SBarry Smith Level: intermediate 10382541af92SBarry Smith 10392541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 104058ebbce7SBarry Smith 1041e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 10422541af92SBarry Smith @*/ 10437087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 10442541af92SBarry Smith { 10452541af92SBarry Smith PetscFunctionBegin; 10460700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10472541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 10482541af92SBarry Smith *nfuncs = snes->nfuncs; 10492541af92SBarry Smith PetscFunctionReturn(0); 10502541af92SBarry Smith } 10512541af92SBarry Smith 10522541af92SBarry Smith #undef __FUNCT__ 10533d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 10543d4c4710SBarry Smith /*@ 10553d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 10563d4c4710SBarry Smith linear solvers. 10573d4c4710SBarry Smith 10583d4c4710SBarry Smith Not Collective 10593d4c4710SBarry Smith 10603d4c4710SBarry Smith Input Parameter: 10613d4c4710SBarry Smith . snes - SNES context 10623d4c4710SBarry Smith 10633d4c4710SBarry Smith Output Parameter: 10643d4c4710SBarry Smith . nfails - number of failed solves 10653d4c4710SBarry Smith 10663d4c4710SBarry Smith Notes: 10673d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 10683d4c4710SBarry Smith 10693d4c4710SBarry Smith Level: intermediate 10703d4c4710SBarry Smith 10713d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 107258ebbce7SBarry Smith 1073e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 10743d4c4710SBarry Smith @*/ 10757087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 10763d4c4710SBarry Smith { 10773d4c4710SBarry Smith PetscFunctionBegin; 10780700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10793d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 10803d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 10813d4c4710SBarry Smith PetscFunctionReturn(0); 10823d4c4710SBarry Smith } 10833d4c4710SBarry Smith 10843d4c4710SBarry Smith #undef __FUNCT__ 10853d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 10863d4c4710SBarry Smith /*@ 10873d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 10883d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 10893d4c4710SBarry Smith 10903f9fe445SBarry Smith Logically Collective on SNES 10913d4c4710SBarry Smith 10923d4c4710SBarry Smith Input Parameters: 10933d4c4710SBarry Smith + snes - SNES context 10943d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 10953d4c4710SBarry Smith 10963d4c4710SBarry Smith Level: intermediate 10973d4c4710SBarry Smith 1098a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 10993d4c4710SBarry Smith 11003d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 11013d4c4710SBarry Smith 110258ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 11033d4c4710SBarry Smith @*/ 11047087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 11053d4c4710SBarry Smith { 11063d4c4710SBarry Smith PetscFunctionBegin; 11070700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1108c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 11093d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 11103d4c4710SBarry Smith PetscFunctionReturn(0); 11113d4c4710SBarry Smith } 11123d4c4710SBarry Smith 11133d4c4710SBarry Smith #undef __FUNCT__ 11143d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 11153d4c4710SBarry Smith /*@ 11163d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 11173d4c4710SBarry Smith are allowed before SNES terminates 11183d4c4710SBarry Smith 11193d4c4710SBarry Smith Not Collective 11203d4c4710SBarry Smith 11213d4c4710SBarry Smith Input Parameter: 11223d4c4710SBarry Smith . snes - SNES context 11233d4c4710SBarry Smith 11243d4c4710SBarry Smith Output Parameter: 11253d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 11263d4c4710SBarry Smith 11273d4c4710SBarry Smith Level: intermediate 11283d4c4710SBarry Smith 11293d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 11303d4c4710SBarry Smith 11313d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 11323d4c4710SBarry Smith 1133e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 11343d4c4710SBarry Smith @*/ 11357087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 11363d4c4710SBarry Smith { 11373d4c4710SBarry Smith PetscFunctionBegin; 11380700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11393d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 11403d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 11413d4c4710SBarry Smith PetscFunctionReturn(0); 11423d4c4710SBarry Smith } 11433d4c4710SBarry Smith 11443d4c4710SBarry Smith #undef __FUNCT__ 1145b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 1146c96a6f78SLois Curfman McInnes /*@ 1147b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1148c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1149c96a6f78SLois Curfman McInnes 1150c7afd0dbSLois Curfman McInnes Not Collective 1151c7afd0dbSLois Curfman McInnes 1152c96a6f78SLois Curfman McInnes Input Parameter: 1153c96a6f78SLois Curfman McInnes . snes - SNES context 1154c96a6f78SLois Curfman McInnes 1155c96a6f78SLois Curfman McInnes Output Parameter: 1156c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1157c96a6f78SLois Curfman McInnes 1158c96a6f78SLois Curfman McInnes Notes: 1159c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1160c96a6f78SLois Curfman McInnes 116136851e7fSLois Curfman McInnes Level: intermediate 116236851e7fSLois Curfman McInnes 1163c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 11642b668275SBarry Smith 11658c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 1166c96a6f78SLois Curfman McInnes @*/ 11677087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 1168c96a6f78SLois Curfman McInnes { 11693a40ed3dSBarry Smith PetscFunctionBegin; 11700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11714482741eSBarry Smith PetscValidIntPointer(lits,2); 1172c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 11733a40ed3dSBarry Smith PetscFunctionReturn(0); 1174c96a6f78SLois Curfman McInnes } 1175c96a6f78SLois Curfman McInnes 11764a2ae208SSatish Balay #undef __FUNCT__ 117794b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 117852baeb72SSatish Balay /*@ 117994b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 11809b94acceSBarry Smith 118194b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 1182c7afd0dbSLois Curfman McInnes 11839b94acceSBarry Smith Input Parameter: 11849b94acceSBarry Smith . snes - the SNES context 11859b94acceSBarry Smith 11869b94acceSBarry Smith Output Parameter: 118794b7f48cSBarry Smith . ksp - the KSP context 11889b94acceSBarry Smith 11899b94acceSBarry Smith Notes: 119094b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 11919b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 11922999313aSBarry Smith PC contexts as well. 11939b94acceSBarry Smith 119436851e7fSLois Curfman McInnes Level: beginner 119536851e7fSLois Curfman McInnes 119694b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 11979b94acceSBarry Smith 11982999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 11999b94acceSBarry Smith @*/ 12007087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 12019b94acceSBarry Smith { 12021cee3971SBarry Smith PetscErrorCode ierr; 12031cee3971SBarry Smith 12043a40ed3dSBarry Smith PetscFunctionBegin; 12050700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12064482741eSBarry Smith PetscValidPointer(ksp,2); 12071cee3971SBarry Smith 12081cee3971SBarry Smith if (!snes->ksp) { 12091cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 12101cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 12111cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 12121cee3971SBarry Smith } 121394b7f48cSBarry Smith *ksp = snes->ksp; 12143a40ed3dSBarry Smith PetscFunctionReturn(0); 12159b94acceSBarry Smith } 121682bf6240SBarry Smith 12174a2ae208SSatish Balay #undef __FUNCT__ 12182999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 12192999313aSBarry Smith /*@ 12202999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 12212999313aSBarry Smith 12222999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 12232999313aSBarry Smith 12242999313aSBarry Smith Input Parameters: 12252999313aSBarry Smith + snes - the SNES context 12262999313aSBarry Smith - ksp - the KSP context 12272999313aSBarry Smith 12282999313aSBarry Smith Notes: 12292999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 12302999313aSBarry Smith so this routine is rarely needed. 12312999313aSBarry Smith 12322999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 12332999313aSBarry Smith decreased by one. 12342999313aSBarry Smith 12352999313aSBarry Smith Level: developer 12362999313aSBarry Smith 12372999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 12382999313aSBarry Smith 12392999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 12402999313aSBarry Smith @*/ 12417087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 12422999313aSBarry Smith { 12432999313aSBarry Smith PetscErrorCode ierr; 12442999313aSBarry Smith 12452999313aSBarry Smith PetscFunctionBegin; 12460700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12470700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 12482999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 12497dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1250906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 12512999313aSBarry Smith snes->ksp = ksp; 12522999313aSBarry Smith PetscFunctionReturn(0); 12532999313aSBarry Smith } 12542999313aSBarry Smith 12557adad957SLisandro Dalcin #if 0 12562999313aSBarry Smith #undef __FUNCT__ 12574a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 12586849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1259e24b481bSBarry Smith { 1260e24b481bSBarry Smith PetscFunctionBegin; 1261e24b481bSBarry Smith PetscFunctionReturn(0); 1262e24b481bSBarry Smith } 12637adad957SLisandro Dalcin #endif 1264e24b481bSBarry Smith 12659b94acceSBarry Smith /* -----------------------------------------------------------*/ 12664a2ae208SSatish Balay #undef __FUNCT__ 12674a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 126852baeb72SSatish Balay /*@ 12699b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 12709b94acceSBarry Smith 1271c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1272c7afd0dbSLois Curfman McInnes 1273c7afd0dbSLois Curfman McInnes Input Parameters: 1274906ed7ccSBarry Smith . comm - MPI communicator 12759b94acceSBarry Smith 12769b94acceSBarry Smith Output Parameter: 12779b94acceSBarry Smith . outsnes - the new SNES context 12789b94acceSBarry Smith 1279c7afd0dbSLois Curfman McInnes Options Database Keys: 1280c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1281c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1282c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1283c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1284c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1285c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1286c1f60f51SBarry Smith 128736851e7fSLois Curfman McInnes Level: beginner 128836851e7fSLois Curfman McInnes 12899b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 12909b94acceSBarry Smith 1291a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1292a8054027SBarry Smith 12939b94acceSBarry Smith @*/ 12947087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 12959b94acceSBarry Smith { 1296dfbe8321SBarry Smith PetscErrorCode ierr; 12979b94acceSBarry Smith SNES snes; 1298fa9f3622SBarry Smith SNESKSPEW *kctx; 129937fcc0dbSBarry Smith 13003a40ed3dSBarry Smith PetscFunctionBegin; 1301ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 13028ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 13038ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 13048ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 13058ba1e511SMatthew Knepley #endif 13068ba1e511SMatthew Knepley 13073194b578SJed Brown ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 13087adad957SLisandro Dalcin 130985385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 13102c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 131188976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 13129b94acceSBarry Smith snes->max_its = 50; 13139750a799SBarry Smith snes->max_funcs = 10000; 13149b94acceSBarry Smith snes->norm = 0.0; 1315fdacfa88SPeter Brune snes->normtype = SNES_NORM_FUNCTION; 1316b4874afaSBarry Smith snes->rtol = 1.e-8; 1317b4874afaSBarry Smith snes->ttol = 0.0; 131870441072SBarry Smith snes->abstol = 1.e-50; 1319c60f73f4SPeter Brune snes->stol = 1.e-8; 13204b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 13219b94acceSBarry Smith snes->nfuncs = 0; 132250ffb88aSMatthew Knepley snes->numFailures = 0; 132350ffb88aSMatthew Knepley snes->maxFailures = 1; 13247a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1325e35cf81dSBarry Smith snes->lagjacobian = 1; 1326a8054027SBarry Smith snes->lagpreconditioner = 1; 1327639f9d9dSBarry Smith snes->numbermonitors = 0; 13289b94acceSBarry Smith snes->data = 0; 13294dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1330186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 13316f24a144SLois Curfman McInnes snes->nwork = 0; 133258c9b817SLisandro Dalcin snes->work = 0; 133358c9b817SLisandro Dalcin snes->nvwork = 0; 133458c9b817SLisandro Dalcin snes->vwork = 0; 1335758f92a0SBarry Smith snes->conv_hist_len = 0; 1336758f92a0SBarry Smith snes->conv_hist_max = 0; 1337758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1338758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1339758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1340e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1341e4ed7901SPeter Brune snes->norm_init = 0.; 1342e4ed7901SPeter Brune snes->norm_init_set = PETSC_FALSE; 1343184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 134489b92e6fSPeter Brune snes->gssweeps = 1; 13459b94acceSBarry Smith 13463d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 13473d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 13483d4c4710SBarry Smith 13499b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 135038f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 13519b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 13529b94acceSBarry Smith kctx->version = 2; 13539b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 13549b94acceSBarry Smith this was too large for some test cases */ 135575567043SBarry Smith kctx->rtol_last = 0.0; 13569b94acceSBarry Smith kctx->rtol_max = .9; 13579b94acceSBarry Smith kctx->gamma = 1.0; 135862d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 135971f87433Sdalcinl kctx->alpha2 = kctx->alpha; 13609b94acceSBarry Smith kctx->threshold = .1; 136175567043SBarry Smith kctx->lresid_last = 0.0; 136275567043SBarry Smith kctx->norm_last = 0.0; 13639b94acceSBarry Smith 13649b94acceSBarry Smith *outsnes = snes; 13653a40ed3dSBarry Smith PetscFunctionReturn(0); 13669b94acceSBarry Smith } 13679b94acceSBarry Smith 13684a2ae208SSatish Balay #undef __FUNCT__ 13694a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 13709b94acceSBarry Smith /*@C 13719b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 13729b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 13739b94acceSBarry Smith equations. 13749b94acceSBarry Smith 13753f9fe445SBarry Smith Logically Collective on SNES 1376fee21e36SBarry Smith 1377c7afd0dbSLois Curfman McInnes Input Parameters: 1378c7afd0dbSLois Curfman McInnes + snes - the SNES context 1379c7afd0dbSLois Curfman McInnes . r - vector to store function value 1380de044059SHong Zhang . func - function evaluation routine 1381c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1382c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 13839b94acceSBarry Smith 1384c7afd0dbSLois Curfman McInnes Calling sequence of func: 13858d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1386c7afd0dbSLois Curfman McInnes 1387c586c404SJed Brown + snes - the SNES context 1388c586c404SJed Brown . x - state at which to evaluate residual 1389c586c404SJed Brown . f - vector to put residual 1390c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 13919b94acceSBarry Smith 13929b94acceSBarry Smith Notes: 13939b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 13949b94acceSBarry Smith $ f'(x) x = -f(x), 1395c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 13969b94acceSBarry Smith 139736851e7fSLois Curfman McInnes Level: beginner 139836851e7fSLois Curfman McInnes 13999b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 14009b94acceSBarry Smith 14018b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard() 14029b94acceSBarry Smith @*/ 14037087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 14049b94acceSBarry Smith { 140585385478SLisandro Dalcin PetscErrorCode ierr; 14066cab3a1bSJed Brown DM dm; 14076cab3a1bSJed Brown 14083a40ed3dSBarry Smith PetscFunctionBegin; 14090700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1410d2a683ecSLisandro Dalcin if (r) { 1411d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1412d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 141385385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 14146bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 141585385478SLisandro Dalcin snes->vec_func = r; 1416d2a683ecSLisandro Dalcin } 14176cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 14186cab3a1bSJed Brown ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr); 14193a40ed3dSBarry Smith PetscFunctionReturn(0); 14209b94acceSBarry Smith } 14219b94acceSBarry Smith 1422646217ecSPeter Brune 1423646217ecSPeter Brune #undef __FUNCT__ 1424e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction" 1425e4ed7901SPeter Brune /*@C 1426e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1427e4ed7901SPeter Brune function norm at the initialization of the method. In some 1428e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1429e4ed7901SPeter Brune SNESSolve. This function allows one to avoid a redundant call 1430e4ed7901SPeter Brune to SNESComputeFunction in that case. 1431e4ed7901SPeter Brune 1432e4ed7901SPeter Brune Logically Collective on SNES 1433e4ed7901SPeter Brune 1434e4ed7901SPeter Brune Input Parameters: 1435e4ed7901SPeter Brune + snes - the SNES context 1436e4ed7901SPeter Brune - f - vector to store function value 1437e4ed7901SPeter Brune 1438e4ed7901SPeter Brune Notes: 1439e4ed7901SPeter Brune This should not be modified during the solution procedure. 1440e4ed7901SPeter Brune 1441e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1442e4ed7901SPeter Brune 1443e4ed7901SPeter Brune Level: developer 1444e4ed7901SPeter Brune 1445e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function 1446e4ed7901SPeter Brune 1447e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm() 1448e4ed7901SPeter Brune @*/ 1449e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1450e4ed7901SPeter Brune { 1451e4ed7901SPeter Brune PetscErrorCode ierr; 1452e4ed7901SPeter Brune Vec vec_func; 1453e4ed7901SPeter Brune 1454e4ed7901SPeter Brune PetscFunctionBegin; 1455e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1456e4ed7901SPeter Brune PetscValidHeaderSpecific(f,VEC_CLASSID,2); 1457e4ed7901SPeter Brune PetscCheckSameComm(snes,1,f,2); 1458e4ed7901SPeter Brune ierr = PetscObjectReference((PetscObject)f);CHKERRQ(ierr); 1459e4ed7901SPeter Brune ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1460e4ed7901SPeter Brune ierr = VecCopy(f, vec_func);CHKERRQ(ierr); 1461217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 1462e4ed7901SPeter Brune PetscFunctionReturn(0); 1463e4ed7901SPeter Brune } 1464e4ed7901SPeter Brune 1465e4ed7901SPeter Brune 1466e4ed7901SPeter Brune #undef __FUNCT__ 1467e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm" 1468e4ed7901SPeter Brune /*@C 1469e4ed7901SPeter Brune SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm 1470e4ed7901SPeter Brune at the initialization of the method. In some instances, the user has precomputed 1471e4ed7901SPeter Brune the function and its norm before calling SNESSolve. This function allows one to 1472e4ed7901SPeter Brune avoid a redundant call to SNESComputeFunction() and VecNorm() in that case. 1473e4ed7901SPeter Brune 1474e4ed7901SPeter Brune Logically Collective on SNES 1475e4ed7901SPeter Brune 1476e4ed7901SPeter Brune Input Parameters: 1477e4ed7901SPeter Brune + snes - the SNES context 1478e4ed7901SPeter Brune - fnorm - the norm of F as set by SNESSetInitialFunction() 1479e4ed7901SPeter Brune 1480e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1481e4ed7901SPeter Brune 1482e4ed7901SPeter Brune Level: developer 1483e4ed7901SPeter Brune 1484e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm 1485e4ed7901SPeter Brune 1486e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction() 1487e4ed7901SPeter Brune @*/ 1488e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm) 1489e4ed7901SPeter Brune { 1490e4ed7901SPeter Brune PetscFunctionBegin; 1491e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1492e4ed7901SPeter Brune snes->norm_init = fnorm; 1493e4ed7901SPeter Brune snes->norm_init_set = PETSC_TRUE; 1494e4ed7901SPeter Brune PetscFunctionReturn(0); 1495e4ed7901SPeter Brune } 1496e4ed7901SPeter Brune 1497e4ed7901SPeter Brune #undef __FUNCT__ 1498*534ebe21SPeter Brune #define __FUNCT__ "SNESSetNormType" 1499*534ebe21SPeter Brune /*@ 1500*534ebe21SPeter Brune SNESSetNormType - Sets the SNESNormType used in covergence and monitoring 1501*534ebe21SPeter Brune of the SNES method. 1502*534ebe21SPeter Brune 1503*534ebe21SPeter Brune Logically Collective on SNES 1504*534ebe21SPeter Brune 1505*534ebe21SPeter Brune Input Parameters: 1506*534ebe21SPeter Brune + snes - the SNES context 1507*534ebe21SPeter Brune - normtype - the type of the norm used 1508*534ebe21SPeter Brune 1509*534ebe21SPeter Brune Notes: 1510*534ebe21SPeter Brune Only certain SNES methods support certain SNESNormTypes. Most require evaluation 1511*534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1512*534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1513*534ebe21SPeter Brune (SNESGS) and the like do not require the norm of the function to be computed, and therfore 1514*534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1515*534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1516*534ebe21SPeter Brune their solution. 1517*534ebe21SPeter Brune 1518*534ebe21SPeter Brune Level: developer 1519*534ebe21SPeter Brune 1520*534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1521*534ebe21SPeter Brune 1522*534ebe21SPeter Brune .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType 1523*534ebe21SPeter Brune @*/ 1524*534ebe21SPeter Brune PetscErrorCode SNESSetNormType(SNES snes, SNESNormType normtype) 1525*534ebe21SPeter Brune { 1526*534ebe21SPeter Brune PetscFunctionBegin; 1527*534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1528*534ebe21SPeter Brune snes->normtype = normtype; 1529*534ebe21SPeter Brune PetscFunctionReturn(0); 1530*534ebe21SPeter Brune } 1531*534ebe21SPeter Brune 1532*534ebe21SPeter Brune 1533*534ebe21SPeter Brune #undef __FUNCT__ 1534*534ebe21SPeter Brune #define __FUNCT__ "SNESGetNormType" 1535*534ebe21SPeter Brune /*@ 1536*534ebe21SPeter Brune SNESGetNormType - Gets the SNESNormType used in covergence and monitoring 1537*534ebe21SPeter Brune of the SNES method. 1538*534ebe21SPeter Brune 1539*534ebe21SPeter Brune Logically Collective on SNES 1540*534ebe21SPeter Brune 1541*534ebe21SPeter Brune Input Parameters: 1542*534ebe21SPeter Brune + snes - the SNES context 1543*534ebe21SPeter Brune - normtype - the type of the norm used 1544*534ebe21SPeter Brune 1545*534ebe21SPeter Brune Level: advanced 1546*534ebe21SPeter Brune 1547*534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1548*534ebe21SPeter Brune 1549*534ebe21SPeter Brune .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType 1550*534ebe21SPeter Brune @*/ 1551*534ebe21SPeter Brune PetscErrorCode SNESGetNormType(SNES snes, SNESNormType *normtype) 1552*534ebe21SPeter Brune { 1553*534ebe21SPeter Brune PetscFunctionBegin; 1554*534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1555*534ebe21SPeter Brune *normtype = snes->normtype; 1556*534ebe21SPeter Brune PetscFunctionReturn(0); 1557*534ebe21SPeter Brune } 1558*534ebe21SPeter Brune 1559*534ebe21SPeter Brune #undef __FUNCT__ 1560646217ecSPeter Brune #define __FUNCT__ "SNESSetGS" 1561c79ef259SPeter Brune /*@C 1562c79ef259SPeter Brune SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for 1563c79ef259SPeter Brune use with composed nonlinear solvers. 1564c79ef259SPeter Brune 1565c79ef259SPeter Brune Input Parameters: 1566c79ef259SPeter Brune + snes - the SNES context 1567c79ef259SPeter Brune . gsfunc - function evaluation routine 1568c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 1569c79ef259SPeter Brune smoother evaluation routine (may be PETSC_NULL) 1570c79ef259SPeter Brune 1571c79ef259SPeter Brune Calling sequence of func: 1572c79ef259SPeter Brune $ func (SNES snes,Vec x,Vec b,void *ctx); 1573c79ef259SPeter Brune 1574c79ef259SPeter Brune + X - solution vector 1575c79ef259SPeter Brune . B - RHS vector 1576d28543b3SPeter Brune - ctx - optional user-defined Gauss-Seidel context 1577c79ef259SPeter Brune 1578c79ef259SPeter Brune Notes: 1579c79ef259SPeter Brune The GS routines are used by the composed nonlinear solver to generate 1580c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1581c79ef259SPeter Brune 1582d28543b3SPeter Brune Level: intermediate 1583c79ef259SPeter Brune 1584d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1585c79ef259SPeter Brune 1586c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS() 1587c79ef259SPeter Brune @*/ 15886cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx) 15896cab3a1bSJed Brown { 15906cab3a1bSJed Brown PetscErrorCode ierr; 15916cab3a1bSJed Brown DM dm; 15926cab3a1bSJed Brown 1593646217ecSPeter Brune PetscFunctionBegin; 15946cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15956cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 15966cab3a1bSJed Brown ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr); 1597646217ecSPeter Brune PetscFunctionReturn(0); 1598646217ecSPeter Brune } 1599646217ecSPeter Brune 1600d25893d9SBarry Smith #undef __FUNCT__ 160189b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps" 160289b92e6fSPeter Brune /*@ 160389b92e6fSPeter Brune SNESSetGSSweeps - Sets the number of sweeps of GS to use. 160489b92e6fSPeter Brune 160589b92e6fSPeter Brune Input Parameters: 160689b92e6fSPeter Brune + snes - the SNES context 160789b92e6fSPeter Brune - sweeps - the number of sweeps of GS to perform. 160889b92e6fSPeter Brune 160989b92e6fSPeter Brune Level: intermediate 161089b92e6fSPeter Brune 161189b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 161289b92e6fSPeter Brune 161389b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps() 161489b92e6fSPeter Brune @*/ 161589b92e6fSPeter Brune 161689b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) { 161789b92e6fSPeter Brune PetscFunctionBegin; 161889b92e6fSPeter Brune snes->gssweeps = sweeps; 161989b92e6fSPeter Brune PetscFunctionReturn(0); 162089b92e6fSPeter Brune } 162189b92e6fSPeter Brune 162289b92e6fSPeter Brune 162389b92e6fSPeter Brune #undef __FUNCT__ 162489b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps" 162589b92e6fSPeter Brune /*@ 162689b92e6fSPeter Brune SNESGetGSSweeps - Gets the number of sweeps GS will use. 162789b92e6fSPeter Brune 162889b92e6fSPeter Brune Input Parameters: 162989b92e6fSPeter Brune . snes - the SNES context 163089b92e6fSPeter Brune 163189b92e6fSPeter Brune Output Parameters: 163289b92e6fSPeter Brune . sweeps - the number of sweeps of GS to perform. 163389b92e6fSPeter Brune 163489b92e6fSPeter Brune Level: intermediate 163589b92e6fSPeter Brune 163689b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 163789b92e6fSPeter Brune 163889b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps() 163989b92e6fSPeter Brune @*/ 164089b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) { 164189b92e6fSPeter Brune PetscFunctionBegin; 164289b92e6fSPeter Brune *sweeps = snes->gssweeps; 164389b92e6fSPeter Brune PetscFunctionReturn(0); 164489b92e6fSPeter Brune } 164589b92e6fSPeter Brune 164689b92e6fSPeter Brune #undef __FUNCT__ 16478b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 16488b0a5094SBarry Smith PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 16498b0a5094SBarry Smith { 16508b0a5094SBarry Smith PetscErrorCode ierr; 16516cab3a1bSJed Brown void *functx,*jacctx; 16526cab3a1bSJed Brown 16538b0a5094SBarry Smith PetscFunctionBegin; 16546cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 16556cab3a1bSJed Brown ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr); 16568b0a5094SBarry Smith /* A(x)*x - b(x) */ 16576cab3a1bSJed Brown ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr); 16586cab3a1bSJed Brown ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr); 16598b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 16608b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 16618b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 16628b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 16638b0a5094SBarry Smith PetscFunctionReturn(0); 16648b0a5094SBarry Smith } 16658b0a5094SBarry Smith 16668b0a5094SBarry Smith #undef __FUNCT__ 16678b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 16688b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 16698b0a5094SBarry Smith { 16708b0a5094SBarry Smith PetscFunctionBegin; 16718b0a5094SBarry Smith *flag = snes->matstruct; 16728b0a5094SBarry Smith PetscFunctionReturn(0); 16738b0a5094SBarry Smith } 16748b0a5094SBarry Smith 16758b0a5094SBarry Smith #undef __FUNCT__ 16768b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 16778b0a5094SBarry Smith /*@C 16780d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 16798b0a5094SBarry Smith 16808b0a5094SBarry Smith Logically Collective on SNES 16818b0a5094SBarry Smith 16828b0a5094SBarry Smith Input Parameters: 16838b0a5094SBarry Smith + snes - the SNES context 16848b0a5094SBarry Smith . r - vector to store function value 16858b0a5094SBarry Smith . func - function evaluation routine 16868b0a5094SBarry 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) 16878b0a5094SBarry Smith . mat - matrix to store A 16888b0a5094SBarry Smith . mfunc - function to compute matrix value 16898b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 16908b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 16918b0a5094SBarry Smith 16928b0a5094SBarry Smith Calling sequence of func: 16938b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 16948b0a5094SBarry Smith 16958b0a5094SBarry Smith + f - function vector 16968b0a5094SBarry Smith - ctx - optional user-defined function context 16978b0a5094SBarry Smith 16988b0a5094SBarry Smith Calling sequence of mfunc: 16998b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 17008b0a5094SBarry Smith 17018b0a5094SBarry Smith + x - input vector 17028b0a5094SBarry 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(), 17038b0a5094SBarry Smith normally just pass mat in this location 17048b0a5094SBarry Smith . mat - form A(x) matrix 17058b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 17068b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 17078b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 17088b0a5094SBarry Smith 17098b0a5094SBarry Smith Notes: 17108b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 17118b0a5094SBarry Smith 17128b0a5094SBarry 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} 17138b0a5094SBarry 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. 17148b0a5094SBarry Smith 17158b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 17168b0a5094SBarry Smith 17170d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 17180d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 17198b0a5094SBarry Smith 17208b0a5094SBarry 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 17218b0a5094SBarry 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 17228b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 17238b0a5094SBarry Smith 17248b0a5094SBarry Smith Level: beginner 17258b0a5094SBarry Smith 17268b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 17278b0a5094SBarry Smith 17280d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard() 17298b0a5094SBarry Smith @*/ 17308b0a5094SBarry 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) 17318b0a5094SBarry Smith { 17328b0a5094SBarry Smith PetscErrorCode ierr; 17338b0a5094SBarry Smith PetscFunctionBegin; 17348b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 17358b0a5094SBarry Smith snes->ops->computepfunction = func; 17368b0a5094SBarry Smith snes->ops->computepjacobian = mfunc; 17378b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 17388b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 17398b0a5094SBarry Smith PetscFunctionReturn(0); 17408b0a5094SBarry Smith } 17418b0a5094SBarry Smith 17428b0a5094SBarry Smith #undef __FUNCT__ 1743d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1744d25893d9SBarry Smith /*@C 1745d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1746d25893d9SBarry Smith 1747d25893d9SBarry Smith Logically Collective on SNES 1748d25893d9SBarry Smith 1749d25893d9SBarry Smith Input Parameters: 1750d25893d9SBarry Smith + snes - the SNES context 1751d25893d9SBarry Smith . func - function evaluation routine 1752d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1753d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1754d25893d9SBarry Smith 1755d25893d9SBarry Smith Calling sequence of func: 1756d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1757d25893d9SBarry Smith 1758d25893d9SBarry Smith . f - function vector 1759d25893d9SBarry Smith - ctx - optional user-defined function context 1760d25893d9SBarry Smith 1761d25893d9SBarry Smith Level: intermediate 1762d25893d9SBarry Smith 1763d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1764d25893d9SBarry Smith 1765d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1766d25893d9SBarry Smith @*/ 1767d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1768d25893d9SBarry Smith { 1769d25893d9SBarry Smith PetscFunctionBegin; 1770d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1771d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1772d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1773d25893d9SBarry Smith PetscFunctionReturn(0); 1774d25893d9SBarry Smith } 1775d25893d9SBarry Smith 17763ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 17773ab0aad5SBarry Smith #undef __FUNCT__ 17781096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 17791096aae1SMatthew Knepley /*@C 17801096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 17811096aae1SMatthew Knepley it assumes a zero right hand side. 17821096aae1SMatthew Knepley 17833f9fe445SBarry Smith Logically Collective on SNES 17841096aae1SMatthew Knepley 17851096aae1SMatthew Knepley Input Parameter: 17861096aae1SMatthew Knepley . snes - the SNES context 17871096aae1SMatthew Knepley 17881096aae1SMatthew Knepley Output Parameter: 1789bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 17901096aae1SMatthew Knepley 17911096aae1SMatthew Knepley Level: intermediate 17921096aae1SMatthew Knepley 17931096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 17941096aae1SMatthew Knepley 179585385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 17961096aae1SMatthew Knepley @*/ 17977087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 17981096aae1SMatthew Knepley { 17991096aae1SMatthew Knepley PetscFunctionBegin; 18000700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 18011096aae1SMatthew Knepley PetscValidPointer(rhs,2); 180285385478SLisandro Dalcin *rhs = snes->vec_rhs; 18031096aae1SMatthew Knepley PetscFunctionReturn(0); 18041096aae1SMatthew Knepley } 18051096aae1SMatthew Knepley 18061096aae1SMatthew Knepley #undef __FUNCT__ 18074a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 18089b94acceSBarry Smith /*@ 180936851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 18109b94acceSBarry Smith SNESSetFunction(). 18119b94acceSBarry Smith 1812c7afd0dbSLois Curfman McInnes Collective on SNES 1813c7afd0dbSLois Curfman McInnes 18149b94acceSBarry Smith Input Parameters: 1815c7afd0dbSLois Curfman McInnes + snes - the SNES context 1816c7afd0dbSLois Curfman McInnes - x - input vector 18179b94acceSBarry Smith 18189b94acceSBarry Smith Output Parameter: 18193638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 18209b94acceSBarry Smith 18211bffabb2SLois Curfman McInnes Notes: 182236851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 182336851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 182436851e7fSLois Curfman McInnes themselves. 182536851e7fSLois Curfman McInnes 182636851e7fSLois Curfman McInnes Level: developer 182736851e7fSLois Curfman McInnes 18289b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 18299b94acceSBarry Smith 1830a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 18319b94acceSBarry Smith @*/ 18327087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 18339b94acceSBarry Smith { 1834dfbe8321SBarry Smith PetscErrorCode ierr; 18356cab3a1bSJed Brown DM dm; 18366cab3a1bSJed Brown SNESDM sdm; 18379b94acceSBarry Smith 18383a40ed3dSBarry Smith PetscFunctionBegin; 18390700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 18400700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 18410700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1842c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1843c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 18444ec14c9cSBarry Smith VecValidValues(x,2,PETSC_TRUE); 1845184914b5SBarry Smith 18466cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18476cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 1848d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 18496cab3a1bSJed Brown if (sdm->computefunction) { 1850d64ed03dSBarry Smith PetscStackPush("SNES user function"); 18516cab3a1bSJed Brown ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 1852d64ed03dSBarry Smith PetscStackPop; 185373250ac0SBarry Smith } else if (snes->dm) { 1854644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1855c90fad12SPeter Brune } else if (snes->vec_rhs) { 1856c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1857644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 185885385478SLisandro Dalcin if (snes->vec_rhs) { 185985385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 18603ab0aad5SBarry Smith } 1861ae3c334cSLois Curfman McInnes snes->nfuncs++; 1862d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 18634ec14c9cSBarry Smith VecValidValues(y,3,PETSC_FALSE); 18643a40ed3dSBarry Smith PetscFunctionReturn(0); 18659b94acceSBarry Smith } 18669b94acceSBarry Smith 18674a2ae208SSatish Balay #undef __FUNCT__ 1868646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1869c79ef259SPeter Brune /*@ 1870c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1871c79ef259SPeter Brune SNESSetGS(). 1872c79ef259SPeter Brune 1873c79ef259SPeter Brune Collective on SNES 1874c79ef259SPeter Brune 1875c79ef259SPeter Brune Input Parameters: 1876c79ef259SPeter Brune + snes - the SNES context 1877c79ef259SPeter Brune . x - input vector 1878c79ef259SPeter Brune - b - rhs vector 1879c79ef259SPeter Brune 1880c79ef259SPeter Brune Output Parameter: 1881c79ef259SPeter Brune . x - new solution vector 1882c79ef259SPeter Brune 1883c79ef259SPeter Brune Notes: 1884c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1885c79ef259SPeter Brune implementations, so most users would not generally call this routine 1886c79ef259SPeter Brune themselves. 1887c79ef259SPeter Brune 1888c79ef259SPeter Brune Level: developer 1889c79ef259SPeter Brune 1890c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1891c79ef259SPeter Brune 1892c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1893c79ef259SPeter Brune @*/ 1894646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1895646217ecSPeter Brune { 1896646217ecSPeter Brune PetscErrorCode ierr; 189789b92e6fSPeter Brune PetscInt i; 18986cab3a1bSJed Brown DM dm; 18996cab3a1bSJed Brown SNESDM sdm; 1900646217ecSPeter Brune 1901646217ecSPeter Brune PetscFunctionBegin; 1902646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1903646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1904646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1905646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 1906646217ecSPeter Brune if(b) PetscCheckSameComm(snes,1,b,3); 19074ec14c9cSBarry Smith if (b) VecValidValues(b,2,PETSC_TRUE); 1908701cf23dSPeter Brune ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 19096cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 19106cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 19116cab3a1bSJed Brown if (sdm->computegs) { 191289b92e6fSPeter Brune for (i = 0; i < snes->gssweeps; i++) { 1913646217ecSPeter Brune PetscStackPush("SNES user GS"); 19146cab3a1bSJed Brown ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 1915646217ecSPeter Brune PetscStackPop; 191689b92e6fSPeter Brune } 1917646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 1918701cf23dSPeter Brune ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 19194ec14c9cSBarry Smith VecValidValues(x,3,PETSC_FALSE); 1920646217ecSPeter Brune PetscFunctionReturn(0); 1921646217ecSPeter Brune } 1922646217ecSPeter Brune 1923646217ecSPeter Brune 1924646217ecSPeter Brune #undef __FUNCT__ 19254a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 192662fef451SLois Curfman McInnes /*@ 192762fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 192862fef451SLois Curfman McInnes set with SNESSetJacobian(). 192962fef451SLois Curfman McInnes 1930c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1931c7afd0dbSLois Curfman McInnes 193262fef451SLois Curfman McInnes Input Parameters: 1933c7afd0dbSLois Curfman McInnes + snes - the SNES context 1934c7afd0dbSLois Curfman McInnes - x - input vector 193562fef451SLois Curfman McInnes 193662fef451SLois Curfman McInnes Output Parameters: 1937c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 193862fef451SLois Curfman McInnes . B - optional preconditioning matrix 19392b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1940fee21e36SBarry Smith 1941e35cf81dSBarry Smith Options Database Keys: 1942e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1943693365a8SJed Brown . -snes_lag_jacobian <lag> 1944693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1945693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1946693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 19474c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1948c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 1949c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 1950c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 1951c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 1952c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 19534c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 1954c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 1955c01495d3SJed Brown 1956e35cf81dSBarry Smith 195762fef451SLois Curfman McInnes Notes: 195862fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 195962fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 196062fef451SLois Curfman McInnes 196194b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1962dc5a77f8SLois Curfman McInnes flag parameter. 196362fef451SLois Curfman McInnes 196436851e7fSLois Curfman McInnes Level: developer 196536851e7fSLois Curfman McInnes 196662fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 196762fef451SLois Curfman McInnes 1968e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 196962fef451SLois Curfman McInnes @*/ 19707087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 19719b94acceSBarry Smith { 1972dfbe8321SBarry Smith PetscErrorCode ierr; 1973ace3abfcSBarry Smith PetscBool flag; 19746cab3a1bSJed Brown DM dm; 19756cab3a1bSJed Brown SNESDM sdm; 19763a40ed3dSBarry Smith 19773a40ed3dSBarry Smith PetscFunctionBegin; 19780700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 19790700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 19804482741eSBarry Smith PetscValidPointer(flg,5); 1981c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 19824ec14c9cSBarry Smith VecValidValues(X,2,PETSC_TRUE); 19836cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 19846cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 19856cab3a1bSJed Brown if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 1986ebd3b9afSBarry Smith 1987ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1988ebd3b9afSBarry Smith 1989fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 1990fe3ffe1eSBarry Smith snes->lagjacobian = -1; 1991fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1992fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 1993e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1994e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1995ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1996ebd3b9afSBarry Smith if (flag) { 1997ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1998ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1999ebd3b9afSBarry Smith } 2000e35cf81dSBarry Smith PetscFunctionReturn(0); 2001e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 2002e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 2003e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 2004ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 2005ebd3b9afSBarry Smith if (flag) { 2006ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2007ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2008ebd3b9afSBarry Smith } 2009e35cf81dSBarry Smith PetscFunctionReturn(0); 2010e35cf81dSBarry Smith } 2011e35cf81dSBarry Smith 2012c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 2013e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 2014d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 20156cab3a1bSJed Brown ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr); 2016d64ed03dSBarry Smith PetscStackPop; 2017d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 2018a8054027SBarry Smith 20193b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 20203b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 20213b4f5425SBarry Smith snes->lagpreconditioner = -1; 20223b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 2023a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 2024a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 2025a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 2026a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 2027a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 2028a8054027SBarry Smith } 2029a8054027SBarry Smith 20306d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 20310700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 20320700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 2033693365a8SJed Brown { 2034693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 2035693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 2036693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 2037693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 2038693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 2039693365a8SJed Brown if (flag || flag_draw || flag_contour) { 2040693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 2041693365a8SJed Brown MatStructure mstruct; 2042693365a8SJed Brown PetscViewer vdraw,vstdout; 20436b3a5b13SJed Brown PetscBool flg; 2044693365a8SJed Brown if (flag_operator) { 2045693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 2046693365a8SJed Brown Bexp = Bexp_mine; 2047693365a8SJed Brown } else { 2048693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 2049693365a8SJed Brown ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 2050693365a8SJed Brown if (flg) Bexp = *B; 2051693365a8SJed Brown else { 2052693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 2053693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 2054693365a8SJed Brown Bexp = Bexp_mine; 2055693365a8SJed Brown } 2056693365a8SJed Brown } 2057693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 2058693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 2059693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 2060693365a8SJed Brown if (flag_draw || flag_contour) { 2061693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2062693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 2063693365a8SJed Brown } else vdraw = PETSC_NULL; 2064693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 2065693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 2066693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 2067693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 2068693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2069693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 2070693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2071693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 2072693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2073693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 2074693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2075693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 2076693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2077693365a8SJed Brown } 2078693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2079693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2080693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 2081693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 2082693365a8SJed Brown } 2083693365a8SJed Brown } 20844c30e9fbSJed Brown { 20856719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 20866719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 20874c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 20886719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 20894c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 20904c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 20916719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 20926719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 20936719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 20946719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 20954c30e9fbSJed Brown Mat Bfd; 20964c30e9fbSJed Brown MatStructure mstruct; 20974c30e9fbSJed Brown PetscViewer vdraw,vstdout; 20984c30e9fbSJed Brown ISColoring iscoloring; 20994c30e9fbSJed Brown MatFDColoring matfdcoloring; 21004c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 21014c30e9fbSJed Brown void *funcctx; 21026719d8e4SJed Brown PetscReal norm1,norm2,normmax; 21034c30e9fbSJed Brown 21044c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 21054c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 21064c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 21074c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 21084c30e9fbSJed Brown 21094c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 21104c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 21114c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 21124c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 21134c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 21144c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 21154c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 21164c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 21174c30e9fbSJed Brown 21184c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 21194c30e9fbSJed Brown if (flag_draw || flag_contour) { 21204c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 21214c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 21224c30e9fbSJed Brown } else vdraw = PETSC_NULL; 21234c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 21246719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 21254c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 21264c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 21276719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 21284c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 21294c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 21304c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 21316719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 21324c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 21336719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 21346719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 21354c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 21364c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 21374c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 21384c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 21394c30e9fbSJed Brown } 21404c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 21416719d8e4SJed Brown 21426719d8e4SJed Brown if (flag_threshold) { 21436719d8e4SJed Brown PetscInt bs,rstart,rend,i; 21446719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 21456719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 21466719d8e4SJed Brown for (i=rstart; i<rend; i++) { 21476719d8e4SJed Brown const PetscScalar *ba,*ca; 21486719d8e4SJed Brown const PetscInt *bj,*cj; 21496719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 21506719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 21516719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 21526719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 21536719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 21546719d8e4SJed Brown for (j=0; j<bn; j++) { 21556719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 21566719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 21576719d8e4SJed Brown maxentrycol = bj[j]; 21586719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 21596719d8e4SJed Brown } 21606719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 21616719d8e4SJed Brown maxdiffcol = bj[j]; 21626719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 21636719d8e4SJed Brown } 21646719d8e4SJed Brown if (rdiff > maxrdiff) { 21656719d8e4SJed Brown maxrdiffcol = bj[j]; 21666719d8e4SJed Brown maxrdiff = rdiff; 21676719d8e4SJed Brown } 21686719d8e4SJed Brown } 21696719d8e4SJed Brown if (maxrdiff > 1) { 21706719d8e4SJed 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); 21716719d8e4SJed Brown for (j=0; j<bn; j++) { 21726719d8e4SJed Brown PetscReal rdiff; 21736719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 21746719d8e4SJed Brown if (rdiff > 1) { 21756719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 21766719d8e4SJed Brown } 21776719d8e4SJed Brown } 21786719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 21796719d8e4SJed Brown } 21806719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 21816719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 21826719d8e4SJed Brown } 21836719d8e4SJed Brown } 21844c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 21854c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 21864c30e9fbSJed Brown } 21874c30e9fbSJed Brown } 21883a40ed3dSBarry Smith PetscFunctionReturn(0); 21899b94acceSBarry Smith } 21909b94acceSBarry Smith 21914a2ae208SSatish Balay #undef __FUNCT__ 21924a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 21939b94acceSBarry Smith /*@C 21949b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2195044dda88SLois Curfman McInnes location to store the matrix. 21969b94acceSBarry Smith 21973f9fe445SBarry Smith Logically Collective on SNES and Mat 2198c7afd0dbSLois Curfman McInnes 21999b94acceSBarry Smith Input Parameters: 2200c7afd0dbSLois Curfman McInnes + snes - the SNES context 22019b94acceSBarry Smith . A - Jacobian matrix 22029b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 2203efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 2204c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 2205efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 22069b94acceSBarry Smith 22079b94acceSBarry Smith Calling sequence of func: 22088d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 22099b94acceSBarry Smith 2210c7afd0dbSLois Curfman McInnes + x - input vector 22119b94acceSBarry Smith . A - Jacobian matrix 22129b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 2213ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 22142b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 2215c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 22169b94acceSBarry Smith 22179b94acceSBarry Smith Notes: 221894b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 22192cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 2220ac21db08SLois Curfman McInnes 2221ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 22229b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 22239b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 22249b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 22259b94acceSBarry Smith throughout the global iterations. 22269b94acceSBarry Smith 222716913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 222816913363SBarry Smith each matrix. 222916913363SBarry Smith 2230a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 2231a8a26c1eSJed Brown must be a MatFDColoring. 2232a8a26c1eSJed Brown 2233c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2234c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2235c3cc8fd1SJed Brown 223636851e7fSLois Curfman McInnes Level: beginner 223736851e7fSLois Curfman McInnes 22389b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 22399b94acceSBarry Smith 22403ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 22419b94acceSBarry Smith @*/ 22427087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 22439b94acceSBarry Smith { 2244dfbe8321SBarry Smith PetscErrorCode ierr; 22456cab3a1bSJed Brown DM dm; 22463a7fca6bSBarry Smith 22473a40ed3dSBarry Smith PetscFunctionBegin; 22480700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 22490700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 22500700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 2251c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 225206975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 22536cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 22546cab3a1bSJed Brown ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr); 22553a7fca6bSBarry Smith if (A) { 22567dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 22576bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 22589b94acceSBarry Smith snes->jacobian = A; 22593a7fca6bSBarry Smith } 22603a7fca6bSBarry Smith if (B) { 22617dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 22626bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 22639b94acceSBarry Smith snes->jacobian_pre = B; 22643a7fca6bSBarry Smith } 22653a40ed3dSBarry Smith PetscFunctionReturn(0); 22669b94acceSBarry Smith } 226762fef451SLois Curfman McInnes 22684a2ae208SSatish Balay #undef __FUNCT__ 22694a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 2270c2aafc4cSSatish Balay /*@C 2271b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2272b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2273b4fd4287SBarry Smith 2274c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2275c7afd0dbSLois Curfman McInnes 2276b4fd4287SBarry Smith Input Parameter: 2277b4fd4287SBarry Smith . snes - the nonlinear solver context 2278b4fd4287SBarry Smith 2279b4fd4287SBarry Smith Output Parameters: 2280c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 2281b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 228270e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 228370e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 2284fee21e36SBarry Smith 228536851e7fSLois Curfman McInnes Level: advanced 228636851e7fSLois Curfman McInnes 2287b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 2288b4fd4287SBarry Smith @*/ 22897087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 2290b4fd4287SBarry Smith { 22916cab3a1bSJed Brown PetscErrorCode ierr; 22926cab3a1bSJed Brown DM dm; 22936cab3a1bSJed Brown SNESDM sdm; 22946cab3a1bSJed Brown 22953a40ed3dSBarry Smith PetscFunctionBegin; 22960700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2297b4fd4287SBarry Smith if (A) *A = snes->jacobian; 2298b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 22996cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 23006cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 23016cab3a1bSJed Brown if (func) *func = sdm->computejacobian; 23026cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 23033a40ed3dSBarry Smith PetscFunctionReturn(0); 2304b4fd4287SBarry Smith } 2305b4fd4287SBarry Smith 23069b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 23079b94acceSBarry Smith 23084a2ae208SSatish Balay #undef __FUNCT__ 23094a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 23109b94acceSBarry Smith /*@ 23119b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2312272ac6f2SLois Curfman McInnes of a nonlinear solver. 23139b94acceSBarry Smith 2314fee21e36SBarry Smith Collective on SNES 2315fee21e36SBarry Smith 2316c7afd0dbSLois Curfman McInnes Input Parameters: 231770e92668SMatthew Knepley . snes - the SNES context 2318c7afd0dbSLois Curfman McInnes 2319272ac6f2SLois Curfman McInnes Notes: 2320272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2321272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2322272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2323272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2324272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2325272ac6f2SLois Curfman McInnes 232636851e7fSLois Curfman McInnes Level: advanced 232736851e7fSLois Curfman McInnes 23289b94acceSBarry Smith .keywords: SNES, nonlinear, setup 23299b94acceSBarry Smith 23309b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 23319b94acceSBarry Smith @*/ 23327087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 23339b94acceSBarry Smith { 2334dfbe8321SBarry Smith PetscErrorCode ierr; 23356cab3a1bSJed Brown DM dm; 23366cab3a1bSJed Brown SNESDM sdm; 23373a40ed3dSBarry Smith 23383a40ed3dSBarry Smith PetscFunctionBegin; 23390700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23404dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 23419b94acceSBarry Smith 23427adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 234385385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 234485385478SLisandro Dalcin } 234585385478SLisandro Dalcin 2346a63bb30eSJed Brown ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 234717186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 234858c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 234958c9b817SLisandro Dalcin 235058c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 235158c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 235258c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 235358c9b817SLisandro Dalcin } 235458c9b817SLisandro Dalcin 23556cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 23566cab3a1bSJed Brown ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */ 23576cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 23586cab3a1bSJed Brown if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc"); 23596cab3a1bSJed Brown if (!snes->vec_func) { 23606cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2361214df951SJed Brown } 2362efd51863SBarry Smith 2363b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 2364b710008aSBarry Smith 2365f1c6b773SPeter Brune if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);} 23669e764e56SPeter Brune 2367d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 2368d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2369d25893d9SBarry Smith } 2370d25893d9SBarry Smith 2371410397dcSLisandro Dalcin if (snes->ops->setup) { 2372410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2373410397dcSLisandro Dalcin } 237458c9b817SLisandro Dalcin 23757aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 23763a40ed3dSBarry Smith PetscFunctionReturn(0); 23779b94acceSBarry Smith } 23789b94acceSBarry Smith 23794a2ae208SSatish Balay #undef __FUNCT__ 238037596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 238137596af1SLisandro Dalcin /*@ 238237596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 238337596af1SLisandro Dalcin 238437596af1SLisandro Dalcin Collective on SNES 238537596af1SLisandro Dalcin 238637596af1SLisandro Dalcin Input Parameter: 238737596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 238837596af1SLisandro Dalcin 2389d25893d9SBarry Smith Level: intermediate 2390d25893d9SBarry Smith 2391d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 239237596af1SLisandro Dalcin 239337596af1SLisandro Dalcin .keywords: SNES, destroy 239437596af1SLisandro Dalcin 239537596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 239637596af1SLisandro Dalcin @*/ 239737596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 239837596af1SLisandro Dalcin { 239937596af1SLisandro Dalcin PetscErrorCode ierr; 240037596af1SLisandro Dalcin 240137596af1SLisandro Dalcin PetscFunctionBegin; 240237596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2403d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2404d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2405d25893d9SBarry Smith snes->user = PETSC_NULL; 2406d25893d9SBarry Smith } 24078a23116dSBarry Smith if (snes->pc) { 24088a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 24098a23116dSBarry Smith } 24108a23116dSBarry Smith 241137596af1SLisandro Dalcin if (snes->ops->reset) { 241237596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 241337596af1SLisandro Dalcin } 24149e764e56SPeter Brune if (snes->ksp) { 24159e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 24169e764e56SPeter Brune } 24179e764e56SPeter Brune 24189e764e56SPeter Brune if (snes->linesearch) { 2419f1c6b773SPeter Brune ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 24209e764e56SPeter Brune } 24219e764e56SPeter Brune 24226bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 24236bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 24246bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 24256bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 24266bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 24276bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2428c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2429c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 243037596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 243137596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 243237596af1SLisandro Dalcin PetscFunctionReturn(0); 243337596af1SLisandro Dalcin } 243437596af1SLisandro Dalcin 243537596af1SLisandro Dalcin #undef __FUNCT__ 24364a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 243752baeb72SSatish Balay /*@ 24389b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 24399b94acceSBarry Smith with SNESCreate(). 24409b94acceSBarry Smith 2441c7afd0dbSLois Curfman McInnes Collective on SNES 2442c7afd0dbSLois Curfman McInnes 24439b94acceSBarry Smith Input Parameter: 24449b94acceSBarry Smith . snes - the SNES context 24459b94acceSBarry Smith 244636851e7fSLois Curfman McInnes Level: beginner 244736851e7fSLois Curfman McInnes 24489b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 24499b94acceSBarry Smith 245063a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 24519b94acceSBarry Smith @*/ 24526bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 24539b94acceSBarry Smith { 24546849ba73SBarry Smith PetscErrorCode ierr; 24553a40ed3dSBarry Smith 24563a40ed3dSBarry Smith PetscFunctionBegin; 24576bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 24586bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 24596bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2460d4bb536fSBarry Smith 24616bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 24628a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 24636b8b9a38SLisandro Dalcin 2464be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 24656bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 24666bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 24676d4c513bSLisandro Dalcin 24686bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 24696bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 2470f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 24716b8b9a38SLisandro Dalcin 24726bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 24736bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 24746bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 24756b8b9a38SLisandro Dalcin } 24766bf464f9SBarry Smith if ((*snes)->conv_malloc) { 24776bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 24786bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 247958c9b817SLisandro Dalcin } 24806bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2481a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 24823a40ed3dSBarry Smith PetscFunctionReturn(0); 24839b94acceSBarry Smith } 24849b94acceSBarry Smith 24859b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 24869b94acceSBarry Smith 24874a2ae208SSatish Balay #undef __FUNCT__ 2488a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2489a8054027SBarry Smith /*@ 2490a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2491a8054027SBarry Smith 24923f9fe445SBarry Smith Logically Collective on SNES 2493a8054027SBarry Smith 2494a8054027SBarry Smith Input Parameters: 2495a8054027SBarry Smith + snes - the SNES context 2496a8054027SBarry 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 24973b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2498a8054027SBarry Smith 2499a8054027SBarry Smith Options Database Keys: 2500a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2501a8054027SBarry Smith 2502a8054027SBarry Smith Notes: 2503a8054027SBarry Smith The default is 1 2504a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2505a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2506a8054027SBarry Smith 2507a8054027SBarry Smith Level: intermediate 2508a8054027SBarry Smith 2509a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2510a8054027SBarry Smith 2511e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2512a8054027SBarry Smith 2513a8054027SBarry Smith @*/ 25147087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2515a8054027SBarry Smith { 2516a8054027SBarry Smith PetscFunctionBegin; 25170700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2518e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2519e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2520c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2521a8054027SBarry Smith snes->lagpreconditioner = lag; 2522a8054027SBarry Smith PetscFunctionReturn(0); 2523a8054027SBarry Smith } 2524a8054027SBarry Smith 2525a8054027SBarry Smith #undef __FUNCT__ 2526efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2527efd51863SBarry Smith /*@ 2528efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2529efd51863SBarry Smith 2530efd51863SBarry Smith Logically Collective on SNES 2531efd51863SBarry Smith 2532efd51863SBarry Smith Input Parameters: 2533efd51863SBarry Smith + snes - the SNES context 2534efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2535efd51863SBarry Smith 2536efd51863SBarry Smith Options Database Keys: 2537efd51863SBarry Smith . -snes_grid_sequence <steps> 2538efd51863SBarry Smith 2539efd51863SBarry Smith Level: intermediate 2540efd51863SBarry Smith 2541c0df2a02SJed Brown Notes: 2542c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2543c0df2a02SJed Brown 2544efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2545efd51863SBarry Smith 2546efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2547efd51863SBarry Smith 2548efd51863SBarry Smith @*/ 2549efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2550efd51863SBarry Smith { 2551efd51863SBarry Smith PetscFunctionBegin; 2552efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2553efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2554efd51863SBarry Smith snes->gridsequence = steps; 2555efd51863SBarry Smith PetscFunctionReturn(0); 2556efd51863SBarry Smith } 2557efd51863SBarry Smith 2558efd51863SBarry Smith #undef __FUNCT__ 2559a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2560a8054027SBarry Smith /*@ 2561a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2562a8054027SBarry Smith 25633f9fe445SBarry Smith Not Collective 2564a8054027SBarry Smith 2565a8054027SBarry Smith Input Parameter: 2566a8054027SBarry Smith . snes - the SNES context 2567a8054027SBarry Smith 2568a8054027SBarry Smith Output Parameter: 2569a8054027SBarry 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 25703b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2571a8054027SBarry Smith 2572a8054027SBarry Smith Options Database Keys: 2573a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2574a8054027SBarry Smith 2575a8054027SBarry Smith Notes: 2576a8054027SBarry Smith The default is 1 2577a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2578a8054027SBarry Smith 2579a8054027SBarry Smith Level: intermediate 2580a8054027SBarry Smith 2581a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2582a8054027SBarry Smith 2583a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2584a8054027SBarry Smith 2585a8054027SBarry Smith @*/ 25867087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2587a8054027SBarry Smith { 2588a8054027SBarry Smith PetscFunctionBegin; 25890700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2590a8054027SBarry Smith *lag = snes->lagpreconditioner; 2591a8054027SBarry Smith PetscFunctionReturn(0); 2592a8054027SBarry Smith } 2593a8054027SBarry Smith 2594a8054027SBarry Smith #undef __FUNCT__ 2595e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2596e35cf81dSBarry Smith /*@ 2597e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2598e35cf81dSBarry Smith often the preconditioner is rebuilt. 2599e35cf81dSBarry Smith 26003f9fe445SBarry Smith Logically Collective on SNES 2601e35cf81dSBarry Smith 2602e35cf81dSBarry Smith Input Parameters: 2603e35cf81dSBarry Smith + snes - the SNES context 2604e35cf81dSBarry 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 2605fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2606e35cf81dSBarry Smith 2607e35cf81dSBarry Smith Options Database Keys: 2608e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2609e35cf81dSBarry Smith 2610e35cf81dSBarry Smith Notes: 2611e35cf81dSBarry Smith The default is 1 2612e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2613fe3ffe1eSBarry 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 2614fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2615e35cf81dSBarry Smith 2616e35cf81dSBarry Smith Level: intermediate 2617e35cf81dSBarry Smith 2618e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2619e35cf81dSBarry Smith 2620e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2621e35cf81dSBarry Smith 2622e35cf81dSBarry Smith @*/ 26237087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2624e35cf81dSBarry Smith { 2625e35cf81dSBarry Smith PetscFunctionBegin; 26260700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2627e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2628e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2629c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2630e35cf81dSBarry Smith snes->lagjacobian = lag; 2631e35cf81dSBarry Smith PetscFunctionReturn(0); 2632e35cf81dSBarry Smith } 2633e35cf81dSBarry Smith 2634e35cf81dSBarry Smith #undef __FUNCT__ 2635e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2636e35cf81dSBarry Smith /*@ 2637e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2638e35cf81dSBarry Smith 26393f9fe445SBarry Smith Not Collective 2640e35cf81dSBarry Smith 2641e35cf81dSBarry Smith Input Parameter: 2642e35cf81dSBarry Smith . snes - the SNES context 2643e35cf81dSBarry Smith 2644e35cf81dSBarry Smith Output Parameter: 2645e35cf81dSBarry 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 2646e35cf81dSBarry Smith the Jacobian is built etc. 2647e35cf81dSBarry Smith 2648e35cf81dSBarry Smith Options Database Keys: 2649e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2650e35cf81dSBarry Smith 2651e35cf81dSBarry Smith Notes: 2652e35cf81dSBarry Smith The default is 1 2653e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2654e35cf81dSBarry Smith 2655e35cf81dSBarry Smith Level: intermediate 2656e35cf81dSBarry Smith 2657e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2658e35cf81dSBarry Smith 2659e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2660e35cf81dSBarry Smith 2661e35cf81dSBarry Smith @*/ 26627087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2663e35cf81dSBarry Smith { 2664e35cf81dSBarry Smith PetscFunctionBegin; 26650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2666e35cf81dSBarry Smith *lag = snes->lagjacobian; 2667e35cf81dSBarry Smith PetscFunctionReturn(0); 2668e35cf81dSBarry Smith } 2669e35cf81dSBarry Smith 2670e35cf81dSBarry Smith #undef __FUNCT__ 26714a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 26729b94acceSBarry Smith /*@ 2673d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 26749b94acceSBarry Smith 26753f9fe445SBarry Smith Logically Collective on SNES 2676c7afd0dbSLois Curfman McInnes 26779b94acceSBarry Smith Input Parameters: 2678c7afd0dbSLois Curfman McInnes + snes - the SNES context 267970441072SBarry Smith . abstol - absolute convergence tolerance 268033174efeSLois Curfman McInnes . rtol - relative convergence tolerance 268133174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 268233174efeSLois Curfman McInnes of the change in the solution between steps 268333174efeSLois Curfman McInnes . maxit - maximum number of iterations 2684c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2685fee21e36SBarry Smith 268633174efeSLois Curfman McInnes Options Database Keys: 268770441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2688c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2689c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2690c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2691c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 26929b94acceSBarry Smith 2693d7a720efSLois Curfman McInnes Notes: 26949b94acceSBarry Smith The default maximum number of iterations is 50. 26959b94acceSBarry Smith The default maximum number of function evaluations is 1000. 26969b94acceSBarry Smith 269736851e7fSLois Curfman McInnes Level: intermediate 269836851e7fSLois Curfman McInnes 269933174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 27009b94acceSBarry Smith 27012492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 27029b94acceSBarry Smith @*/ 27037087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 27049b94acceSBarry Smith { 27053a40ed3dSBarry Smith PetscFunctionBegin; 27060700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2707c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2708c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2709c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2710c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2711c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2712c5eb9154SBarry Smith 2713ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2714ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2715ab54825eSJed Brown snes->abstol = abstol; 2716ab54825eSJed Brown } 2717ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2718ab54825eSJed 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); 2719ab54825eSJed Brown snes->rtol = rtol; 2720ab54825eSJed Brown } 2721ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2722ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2723c60f73f4SPeter Brune snes->stol = stol; 2724ab54825eSJed Brown } 2725ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2726ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2727ab54825eSJed Brown snes->max_its = maxit; 2728ab54825eSJed Brown } 2729ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2730ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2731ab54825eSJed Brown snes->max_funcs = maxf; 2732ab54825eSJed Brown } 273388976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 27343a40ed3dSBarry Smith PetscFunctionReturn(0); 27359b94acceSBarry Smith } 27369b94acceSBarry Smith 27374a2ae208SSatish Balay #undef __FUNCT__ 27384a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 27399b94acceSBarry Smith /*@ 274033174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 274133174efeSLois Curfman McInnes 2742c7afd0dbSLois Curfman McInnes Not Collective 2743c7afd0dbSLois Curfman McInnes 274433174efeSLois Curfman McInnes Input Parameters: 2745c7afd0dbSLois Curfman McInnes + snes - the SNES context 274685385478SLisandro Dalcin . atol - absolute convergence tolerance 274733174efeSLois Curfman McInnes . rtol - relative convergence tolerance 274833174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 274933174efeSLois Curfman McInnes of the change in the solution between steps 275033174efeSLois Curfman McInnes . maxit - maximum number of iterations 2751c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2752fee21e36SBarry Smith 275333174efeSLois Curfman McInnes Notes: 275433174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 275533174efeSLois Curfman McInnes 275636851e7fSLois Curfman McInnes Level: intermediate 275736851e7fSLois Curfman McInnes 275833174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 275933174efeSLois Curfman McInnes 276033174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 276133174efeSLois Curfman McInnes @*/ 27627087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 276333174efeSLois Curfman McInnes { 27643a40ed3dSBarry Smith PetscFunctionBegin; 27650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 276685385478SLisandro Dalcin if (atol) *atol = snes->abstol; 276733174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 2768c60f73f4SPeter Brune if (stol) *stol = snes->stol; 276933174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 277033174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 27713a40ed3dSBarry Smith PetscFunctionReturn(0); 277233174efeSLois Curfman McInnes } 277333174efeSLois Curfman McInnes 27744a2ae208SSatish Balay #undef __FUNCT__ 27754a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 277633174efeSLois Curfman McInnes /*@ 27779b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 27789b94acceSBarry Smith 27793f9fe445SBarry Smith Logically Collective on SNES 2780fee21e36SBarry Smith 2781c7afd0dbSLois Curfman McInnes Input Parameters: 2782c7afd0dbSLois Curfman McInnes + snes - the SNES context 2783c7afd0dbSLois Curfman McInnes - tol - tolerance 2784c7afd0dbSLois Curfman McInnes 27859b94acceSBarry Smith Options Database Key: 2786c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 27879b94acceSBarry Smith 278836851e7fSLois Curfman McInnes Level: intermediate 278936851e7fSLois Curfman McInnes 27909b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 27919b94acceSBarry Smith 27922492ecdbSBarry Smith .seealso: SNESSetTolerances() 27939b94acceSBarry Smith @*/ 27947087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 27959b94acceSBarry Smith { 27963a40ed3dSBarry Smith PetscFunctionBegin; 27970700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2798c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 27999b94acceSBarry Smith snes->deltatol = tol; 28003a40ed3dSBarry Smith PetscFunctionReturn(0); 28019b94acceSBarry Smith } 28029b94acceSBarry Smith 2803df9fa365SBarry Smith /* 2804df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2805df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2806df9fa365SBarry Smith macros instead of functions 2807df9fa365SBarry Smith */ 28084a2ae208SSatish Balay #undef __FUNCT__ 2809a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 28107087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2811ce1608b8SBarry Smith { 2812dfbe8321SBarry Smith PetscErrorCode ierr; 2813ce1608b8SBarry Smith 2814ce1608b8SBarry Smith PetscFunctionBegin; 28150700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2816a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2817ce1608b8SBarry Smith PetscFunctionReturn(0); 2818ce1608b8SBarry Smith } 2819ce1608b8SBarry Smith 28204a2ae208SSatish Balay #undef __FUNCT__ 2821a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 28227087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2823df9fa365SBarry Smith { 2824dfbe8321SBarry Smith PetscErrorCode ierr; 2825df9fa365SBarry Smith 2826df9fa365SBarry Smith PetscFunctionBegin; 2827a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2828df9fa365SBarry Smith PetscFunctionReturn(0); 2829df9fa365SBarry Smith } 2830df9fa365SBarry Smith 28314a2ae208SSatish Balay #undef __FUNCT__ 2832a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 28336bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2834df9fa365SBarry Smith { 2835dfbe8321SBarry Smith PetscErrorCode ierr; 2836df9fa365SBarry Smith 2837df9fa365SBarry Smith PetscFunctionBegin; 2838a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2839df9fa365SBarry Smith PetscFunctionReturn(0); 2840df9fa365SBarry Smith } 2841df9fa365SBarry Smith 28427087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2843b271bb04SBarry Smith #undef __FUNCT__ 2844b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 28457087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2846b271bb04SBarry Smith { 2847b271bb04SBarry Smith PetscDrawLG lg; 2848b271bb04SBarry Smith PetscErrorCode ierr; 2849b271bb04SBarry Smith PetscReal x,y,per; 2850b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2851b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2852b271bb04SBarry Smith PetscDraw draw; 2853b271bb04SBarry Smith PetscFunctionBegin; 2854b271bb04SBarry Smith if (!monctx) { 2855b271bb04SBarry Smith MPI_Comm comm; 2856b271bb04SBarry Smith 2857b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2858b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2859b271bb04SBarry Smith } 2860b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2861b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2862b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2863b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2864b271bb04SBarry Smith x = (PetscReal) n; 2865b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2866b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2867b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2868b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2869b271bb04SBarry Smith } 2870b271bb04SBarry Smith 2871b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2872b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2873b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2874b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2875b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2876b271bb04SBarry Smith x = (PetscReal) n; 2877b271bb04SBarry Smith y = 100.0*per; 2878b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2879b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2880b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2881b271bb04SBarry Smith } 2882b271bb04SBarry Smith 2883b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2884b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2885b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2886b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2887b271bb04SBarry Smith x = (PetscReal) n; 2888b271bb04SBarry Smith y = (prev - rnorm)/prev; 2889b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2890b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2891b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2892b271bb04SBarry Smith } 2893b271bb04SBarry Smith 2894b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2895b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2896b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2897b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2898b271bb04SBarry Smith x = (PetscReal) n; 2899b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2900b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2901b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2902b271bb04SBarry Smith } 2903b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2904b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2905b271bb04SBarry Smith } 2906b271bb04SBarry Smith prev = rnorm; 2907b271bb04SBarry Smith PetscFunctionReturn(0); 2908b271bb04SBarry Smith } 2909b271bb04SBarry Smith 2910b271bb04SBarry Smith #undef __FUNCT__ 2911b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 29127087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2913b271bb04SBarry Smith { 2914b271bb04SBarry Smith PetscErrorCode ierr; 2915b271bb04SBarry Smith 2916b271bb04SBarry Smith PetscFunctionBegin; 2917b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2918b271bb04SBarry Smith PetscFunctionReturn(0); 2919b271bb04SBarry Smith } 2920b271bb04SBarry Smith 2921b271bb04SBarry Smith #undef __FUNCT__ 2922b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 29236bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2924b271bb04SBarry Smith { 2925b271bb04SBarry Smith PetscErrorCode ierr; 2926b271bb04SBarry Smith 2927b271bb04SBarry Smith PetscFunctionBegin; 2928b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2929b271bb04SBarry Smith PetscFunctionReturn(0); 2930b271bb04SBarry Smith } 2931b271bb04SBarry Smith 29327a03ce2fSLisandro Dalcin #undef __FUNCT__ 29337a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 2934228d79bcSJed Brown /*@ 2935228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 2936228d79bcSJed Brown 2937228d79bcSJed Brown Collective on SNES 2938228d79bcSJed Brown 2939228d79bcSJed Brown Input Parameters: 2940228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 2941228d79bcSJed Brown . iter - iteration number 2942228d79bcSJed Brown - rnorm - relative norm of the residual 2943228d79bcSJed Brown 2944228d79bcSJed Brown Notes: 2945228d79bcSJed Brown This routine is called by the SNES implementations. 2946228d79bcSJed Brown It does not typically need to be called by the user. 2947228d79bcSJed Brown 2948228d79bcSJed Brown Level: developer 2949228d79bcSJed Brown 2950228d79bcSJed Brown .seealso: SNESMonitorSet() 2951228d79bcSJed Brown @*/ 29527a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 29537a03ce2fSLisandro Dalcin { 29547a03ce2fSLisandro Dalcin PetscErrorCode ierr; 29557a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 29567a03ce2fSLisandro Dalcin 29577a03ce2fSLisandro Dalcin PetscFunctionBegin; 29587a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 29597a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 29607a03ce2fSLisandro Dalcin } 29617a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 29627a03ce2fSLisandro Dalcin } 29637a03ce2fSLisandro Dalcin 29649b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 29659b94acceSBarry Smith 29664a2ae208SSatish Balay #undef __FUNCT__ 2967a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 29689b94acceSBarry Smith /*@C 2969a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 29709b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 29719b94acceSBarry Smith progress. 29729b94acceSBarry Smith 29733f9fe445SBarry Smith Logically Collective on SNES 2974fee21e36SBarry Smith 2975c7afd0dbSLois Curfman McInnes Input Parameters: 2976c7afd0dbSLois Curfman McInnes + snes - the SNES context 2977c7afd0dbSLois Curfman McInnes . func - monitoring routine 2978b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 2979e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 2980b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 2981b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 29829b94acceSBarry Smith 2983c7afd0dbSLois Curfman McInnes Calling sequence of func: 2984a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2985c7afd0dbSLois Curfman McInnes 2986c7afd0dbSLois Curfman McInnes + snes - the SNES context 2987c7afd0dbSLois Curfman McInnes . its - iteration number 2988c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 298940a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 29909b94acceSBarry Smith 29919665c990SLois Curfman McInnes Options Database Keys: 2992a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 2993a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 2994a6570f20SBarry Smith uses SNESMonitorLGCreate() 2995cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 2996c7afd0dbSLois Curfman McInnes been hardwired into a code by 2997a6570f20SBarry Smith calls to SNESMonitorSet(), but 2998c7afd0dbSLois Curfman McInnes does not cancel those set via 2999c7afd0dbSLois Curfman McInnes the options database. 30009665c990SLois Curfman McInnes 3001639f9d9dSBarry Smith Notes: 30026bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 3003a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 30046bc08f3fSLois Curfman McInnes order in which they were set. 3005639f9d9dSBarry Smith 3006025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 3007025f1a04SBarry Smith 300836851e7fSLois Curfman McInnes Level: intermediate 300936851e7fSLois Curfman McInnes 30109b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 30119b94acceSBarry Smith 3012a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 30139b94acceSBarry Smith @*/ 3014c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 30159b94acceSBarry Smith { 3016b90d0a6eSBarry Smith PetscInt i; 3017649052a6SBarry Smith PetscErrorCode ierr; 3018b90d0a6eSBarry Smith 30193a40ed3dSBarry Smith PetscFunctionBegin; 30200700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 302117186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 3022b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 3023649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 3024649052a6SBarry Smith if (monitordestroy) { 3025c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 3026649052a6SBarry Smith } 3027b90d0a6eSBarry Smith PetscFunctionReturn(0); 3028b90d0a6eSBarry Smith } 3029b90d0a6eSBarry Smith } 3030b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 3031b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 3032639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 30333a40ed3dSBarry Smith PetscFunctionReturn(0); 30349b94acceSBarry Smith } 30359b94acceSBarry Smith 30364a2ae208SSatish Balay #undef __FUNCT__ 3037a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 30385cd90555SBarry Smith /*@C 3039a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 30405cd90555SBarry Smith 30413f9fe445SBarry Smith Logically Collective on SNES 3042c7afd0dbSLois Curfman McInnes 30435cd90555SBarry Smith Input Parameters: 30445cd90555SBarry Smith . snes - the SNES context 30455cd90555SBarry Smith 30461a480d89SAdministrator Options Database Key: 3047a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 3048a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 3049c7afd0dbSLois Curfman McInnes set via the options database 30505cd90555SBarry Smith 30515cd90555SBarry Smith Notes: 30525cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 30535cd90555SBarry Smith 305436851e7fSLois Curfman McInnes Level: intermediate 305536851e7fSLois Curfman McInnes 30565cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 30575cd90555SBarry Smith 3058a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 30595cd90555SBarry Smith @*/ 30607087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 30615cd90555SBarry Smith { 3062d952e501SBarry Smith PetscErrorCode ierr; 3063d952e501SBarry Smith PetscInt i; 3064d952e501SBarry Smith 30655cd90555SBarry Smith PetscFunctionBegin; 30660700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3067d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 3068d952e501SBarry Smith if (snes->monitordestroy[i]) { 30693c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 3070d952e501SBarry Smith } 3071d952e501SBarry Smith } 30725cd90555SBarry Smith snes->numbermonitors = 0; 30735cd90555SBarry Smith PetscFunctionReturn(0); 30745cd90555SBarry Smith } 30755cd90555SBarry Smith 30764a2ae208SSatish Balay #undef __FUNCT__ 30774a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 30789b94acceSBarry Smith /*@C 30799b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 30809b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 30819b94acceSBarry Smith 30823f9fe445SBarry Smith Logically Collective on SNES 3083fee21e36SBarry Smith 3084c7afd0dbSLois Curfman McInnes Input Parameters: 3085c7afd0dbSLois Curfman McInnes + snes - the SNES context 3086c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 30877f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 30887f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 30899b94acceSBarry Smith 3090c7afd0dbSLois Curfman McInnes Calling sequence of func: 309106ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 3092c7afd0dbSLois Curfman McInnes 3093c7afd0dbSLois Curfman McInnes + snes - the SNES context 309406ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 3095c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 3096184914b5SBarry Smith . reason - reason for convergence/divergence 3097c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 30984b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 30994b27c08aSLois Curfman McInnes - f - 2-norm of function 31009b94acceSBarry Smith 310136851e7fSLois Curfman McInnes Level: advanced 310236851e7fSLois Curfman McInnes 31039b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 31049b94acceSBarry Smith 310585385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 31069b94acceSBarry Smith @*/ 31077087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 31089b94acceSBarry Smith { 31097f7931b9SBarry Smith PetscErrorCode ierr; 31107f7931b9SBarry Smith 31113a40ed3dSBarry Smith PetscFunctionBegin; 31120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 311385385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 31147f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 31157f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 31167f7931b9SBarry Smith } 311785385478SLisandro Dalcin snes->ops->converged = func; 31187f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 311985385478SLisandro Dalcin snes->cnvP = cctx; 31203a40ed3dSBarry Smith PetscFunctionReturn(0); 31219b94acceSBarry Smith } 31229b94acceSBarry Smith 31234a2ae208SSatish Balay #undef __FUNCT__ 31244a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 312552baeb72SSatish Balay /*@ 3126184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 3127184914b5SBarry Smith 3128184914b5SBarry Smith Not Collective 3129184914b5SBarry Smith 3130184914b5SBarry Smith Input Parameter: 3131184914b5SBarry Smith . snes - the SNES context 3132184914b5SBarry Smith 3133184914b5SBarry Smith Output Parameter: 31344d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 3135184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 3136184914b5SBarry Smith 3137184914b5SBarry Smith Level: intermediate 3138184914b5SBarry Smith 3139184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 3140184914b5SBarry Smith 3141184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 3142184914b5SBarry Smith 314385385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 3144184914b5SBarry Smith @*/ 31457087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 3146184914b5SBarry Smith { 3147184914b5SBarry Smith PetscFunctionBegin; 31480700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31494482741eSBarry Smith PetscValidPointer(reason,2); 3150184914b5SBarry Smith *reason = snes->reason; 3151184914b5SBarry Smith PetscFunctionReturn(0); 3152184914b5SBarry Smith } 3153184914b5SBarry Smith 31544a2ae208SSatish Balay #undef __FUNCT__ 31554a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 3156c9005455SLois Curfman McInnes /*@ 3157c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 3158c9005455SLois Curfman McInnes 31593f9fe445SBarry Smith Logically Collective on SNES 3160fee21e36SBarry Smith 3161c7afd0dbSLois Curfman McInnes Input Parameters: 3162c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 31638c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 3164cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 3165758f92a0SBarry Smith . na - size of a and its 316664731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 3167758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 3168c7afd0dbSLois Curfman McInnes 3169308dcc3eSBarry Smith Notes: 3170308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 3171308dcc3eSBarry Smith default array of length 10000 is allocated. 3172308dcc3eSBarry Smith 3173c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 3174c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 3175c9005455SLois Curfman McInnes during the section of code that is being timed. 3176c9005455SLois Curfman McInnes 317736851e7fSLois Curfman McInnes Level: intermediate 317836851e7fSLois Curfman McInnes 3179c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 3180758f92a0SBarry Smith 318108405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 3182758f92a0SBarry Smith 3183c9005455SLois Curfman McInnes @*/ 31847087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 3185c9005455SLois Curfman McInnes { 3186308dcc3eSBarry Smith PetscErrorCode ierr; 3187308dcc3eSBarry Smith 31883a40ed3dSBarry Smith PetscFunctionBegin; 31890700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31904482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 3191a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 3192308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 3193308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 3194308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 3195308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 3196308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 3197308dcc3eSBarry Smith } 3198c9005455SLois Curfman McInnes snes->conv_hist = a; 3199758f92a0SBarry Smith snes->conv_hist_its = its; 3200758f92a0SBarry Smith snes->conv_hist_max = na; 3201a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 3202758f92a0SBarry Smith snes->conv_hist_reset = reset; 3203758f92a0SBarry Smith PetscFunctionReturn(0); 3204758f92a0SBarry Smith } 3205758f92a0SBarry Smith 3206308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3207c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 3208c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 3209308dcc3eSBarry Smith EXTERN_C_BEGIN 3210308dcc3eSBarry Smith #undef __FUNCT__ 3211308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 3212308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3213308dcc3eSBarry Smith { 3214308dcc3eSBarry Smith mxArray *mat; 3215308dcc3eSBarry Smith PetscInt i; 3216308dcc3eSBarry Smith PetscReal *ar; 3217308dcc3eSBarry Smith 3218308dcc3eSBarry Smith PetscFunctionBegin; 3219308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3220308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3221308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 3222308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 3223308dcc3eSBarry Smith } 3224308dcc3eSBarry Smith PetscFunctionReturn(mat); 3225308dcc3eSBarry Smith } 3226308dcc3eSBarry Smith EXTERN_C_END 3227308dcc3eSBarry Smith #endif 3228308dcc3eSBarry Smith 3229308dcc3eSBarry Smith 32304a2ae208SSatish Balay #undef __FUNCT__ 32314a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 32320c4c9dddSBarry Smith /*@C 3233758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3234758f92a0SBarry Smith 32353f9fe445SBarry Smith Not Collective 3236758f92a0SBarry Smith 3237758f92a0SBarry Smith Input Parameter: 3238758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3239758f92a0SBarry Smith 3240758f92a0SBarry Smith Output Parameters: 3241758f92a0SBarry Smith . a - array to hold history 3242758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3243758f92a0SBarry Smith negative if not converged) for each solve. 3244758f92a0SBarry Smith - na - size of a and its 3245758f92a0SBarry Smith 3246758f92a0SBarry Smith Notes: 3247758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3248758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3249758f92a0SBarry Smith 3250758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3251758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3252758f92a0SBarry Smith during the section of code that is being timed. 3253758f92a0SBarry Smith 3254758f92a0SBarry Smith Level: intermediate 3255758f92a0SBarry Smith 3256758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3257758f92a0SBarry Smith 3258758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3259758f92a0SBarry Smith 3260758f92a0SBarry Smith @*/ 32617087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3262758f92a0SBarry Smith { 3263758f92a0SBarry Smith PetscFunctionBegin; 32640700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3265758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3266758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3267758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 32683a40ed3dSBarry Smith PetscFunctionReturn(0); 3269c9005455SLois Curfman McInnes } 3270c9005455SLois Curfman McInnes 3271e74ef692SMatthew Knepley #undef __FUNCT__ 3272e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 3273ac226902SBarry Smith /*@C 327476b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3275eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 32767e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 327776b2cf59SMatthew Knepley 32783f9fe445SBarry Smith Logically Collective on SNES 327976b2cf59SMatthew Knepley 328076b2cf59SMatthew Knepley Input Parameters: 328176b2cf59SMatthew Knepley . snes - The nonlinear solver context 328276b2cf59SMatthew Knepley . func - The function 328376b2cf59SMatthew Knepley 328476b2cf59SMatthew Knepley Calling sequence of func: 3285b5d30489SBarry Smith . func (SNES snes, PetscInt step); 328676b2cf59SMatthew Knepley 328776b2cf59SMatthew Knepley . step - The current step of the iteration 328876b2cf59SMatthew Knepley 3289fe97e370SBarry Smith Level: advanced 3290fe97e370SBarry Smith 3291fe97e370SBarry 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() 3292fe97e370SBarry Smith This is not used by most users. 329376b2cf59SMatthew Knepley 329476b2cf59SMatthew Knepley .keywords: SNES, update 3295b5d30489SBarry Smith 329685385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 329776b2cf59SMatthew Knepley @*/ 32987087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 329976b2cf59SMatthew Knepley { 330076b2cf59SMatthew Knepley PetscFunctionBegin; 33010700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3302e7788613SBarry Smith snes->ops->update = func; 330376b2cf59SMatthew Knepley PetscFunctionReturn(0); 330476b2cf59SMatthew Knepley } 330576b2cf59SMatthew Knepley 3306e74ef692SMatthew Knepley #undef __FUNCT__ 3307e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 330876b2cf59SMatthew Knepley /*@ 330976b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 331076b2cf59SMatthew Knepley 331176b2cf59SMatthew Knepley Not collective 331276b2cf59SMatthew Knepley 331376b2cf59SMatthew Knepley Input Parameters: 331476b2cf59SMatthew Knepley . snes - The nonlinear solver context 331576b2cf59SMatthew Knepley . step - The current step of the iteration 331676b2cf59SMatthew Knepley 3317205452f4SMatthew Knepley Level: intermediate 3318205452f4SMatthew Knepley 331976b2cf59SMatthew Knepley .keywords: SNES, update 3320a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 332176b2cf59SMatthew Knepley @*/ 33227087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 332376b2cf59SMatthew Knepley { 332476b2cf59SMatthew Knepley PetscFunctionBegin; 332576b2cf59SMatthew Knepley PetscFunctionReturn(0); 332676b2cf59SMatthew Knepley } 332776b2cf59SMatthew Knepley 33284a2ae208SSatish Balay #undef __FUNCT__ 33294a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 33309b94acceSBarry Smith /* 33319b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 33329b94acceSBarry Smith positive parameter delta. 33339b94acceSBarry Smith 33349b94acceSBarry Smith Input Parameters: 3335c7afd0dbSLois Curfman McInnes + snes - the SNES context 33369b94acceSBarry Smith . y - approximate solution of linear system 33379b94acceSBarry Smith . fnorm - 2-norm of current function 3338c7afd0dbSLois Curfman McInnes - delta - trust region size 33399b94acceSBarry Smith 33409b94acceSBarry Smith Output Parameters: 3341c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 33429b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 33439b94acceSBarry Smith region, and exceeds zero otherwise. 3344c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 33459b94acceSBarry Smith 33469b94acceSBarry Smith Note: 33474b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 33489b94acceSBarry Smith is set to be the maximum allowable step size. 33499b94acceSBarry Smith 33509b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 33519b94acceSBarry Smith */ 3352dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 33539b94acceSBarry Smith { 3354064f8208SBarry Smith PetscReal nrm; 3355ea709b57SSatish Balay PetscScalar cnorm; 3356dfbe8321SBarry Smith PetscErrorCode ierr; 33573a40ed3dSBarry Smith 33583a40ed3dSBarry Smith PetscFunctionBegin; 33590700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 33600700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3361c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3362184914b5SBarry Smith 3363064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3364064f8208SBarry Smith if (nrm > *delta) { 3365064f8208SBarry Smith nrm = *delta/nrm; 3366064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3367064f8208SBarry Smith cnorm = nrm; 33682dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 33699b94acceSBarry Smith *ynorm = *delta; 33709b94acceSBarry Smith } else { 33719b94acceSBarry Smith *gpnorm = 0.0; 3372064f8208SBarry Smith *ynorm = nrm; 33739b94acceSBarry Smith } 33743a40ed3dSBarry Smith PetscFunctionReturn(0); 33759b94acceSBarry Smith } 33769b94acceSBarry Smith 33774a2ae208SSatish Balay #undef __FUNCT__ 33784a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 33796ce558aeSBarry Smith /*@C 3380f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3381f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 33829b94acceSBarry Smith 3383c7afd0dbSLois Curfman McInnes Collective on SNES 3384c7afd0dbSLois Curfman McInnes 3385b2002411SLois Curfman McInnes Input Parameters: 3386c7afd0dbSLois Curfman McInnes + snes - the SNES context 33873cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 338885385478SLisandro Dalcin - x - the solution vector. 33899b94acceSBarry Smith 3390b2002411SLois Curfman McInnes Notes: 33918ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 33928ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 33938ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 33948ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 33958ddd3da0SLois Curfman McInnes 339636851e7fSLois Curfman McInnes Level: beginner 339736851e7fSLois Curfman McInnes 33989b94acceSBarry Smith .keywords: SNES, nonlinear, solve 33999b94acceSBarry Smith 3400c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 34019b94acceSBarry Smith @*/ 34027087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 34039b94acceSBarry Smith { 3404dfbe8321SBarry Smith PetscErrorCode ierr; 3405ace3abfcSBarry Smith PetscBool flg; 3406eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 3407eabae89aSBarry Smith PetscViewer viewer; 3408efd51863SBarry Smith PetscInt grid; 3409a69afd8bSBarry Smith Vec xcreated = PETSC_NULL; 3410caa4e7f2SJed Brown DM dm; 3411052efed2SBarry Smith 34123a40ed3dSBarry Smith PetscFunctionBegin; 34130700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3414a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3415a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 34160700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 341785385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 341885385478SLisandro Dalcin 3419caa4e7f2SJed Brown if (!x) { 3420caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3421caa4e7f2SJed Brown ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 3422a69afd8bSBarry Smith x = xcreated; 3423a69afd8bSBarry Smith } 3424a69afd8bSBarry Smith 3425a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3426efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3427efd51863SBarry Smith 342885385478SLisandro Dalcin /* set solution vector */ 3429efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 34306bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 343185385478SLisandro Dalcin snes->vec_sol = x; 3432caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3433caa4e7f2SJed Brown 3434caa4e7f2SJed Brown /* set affine vector if provided */ 343585385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 34366bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 343785385478SLisandro Dalcin snes->vec_rhs = b; 343885385478SLisandro Dalcin 343970e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 34403f149594SLisandro Dalcin 34417eee914bSBarry Smith if (!grid) { 34427eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3443d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3444dd568438SSatish Balay } else if (snes->dm) { 3445dd568438SSatish Balay PetscBool ig; 3446dd568438SSatish Balay ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr); 3447dd568438SSatish Balay if (ig) { 34487eee914bSBarry Smith ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr); 34497eee914bSBarry Smith } 3450d25893d9SBarry Smith } 3451dd568438SSatish Balay } 3452d25893d9SBarry Smith 3453abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 345450ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3455d5e45103SBarry Smith 34563f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 34574936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 345885385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 34594936397dSBarry Smith if (snes->domainerror){ 34604936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 34614936397dSBarry Smith snes->domainerror = PETSC_FALSE; 34624936397dSBarry Smith } 346317186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 34643f149594SLisandro Dalcin 34657adad957SLisandro Dalcin ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 3466eabae89aSBarry Smith if (flg && !PetscPreLoadingOn) { 34677adad957SLisandro Dalcin ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 3468eabae89aSBarry Smith ierr = SNESView(snes,viewer);CHKERRQ(ierr); 34696bf464f9SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3470eabae89aSBarry Smith } 3471eabae89aSBarry Smith 347290d69ab7SBarry Smith flg = PETSC_FALSE; 3473acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3474da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 34755968eb51SBarry Smith if (snes->printreason) { 3476a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 34775968eb51SBarry Smith if (snes->reason > 0) { 3478c7e7b494SJed 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); 34795968eb51SBarry Smith } else { 3480c7e7b494SJed 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); 34815968eb51SBarry Smith } 3482a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 34835968eb51SBarry Smith } 34845968eb51SBarry Smith 34858501fc72SJed Brown flg = PETSC_FALSE; 34868501fc72SJed Brown ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 34878501fc72SJed Brown if (flg) { 34888501fc72SJed Brown PetscViewer viewer; 34898501fc72SJed Brown ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 34908501fc72SJed Brown ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 34918501fc72SJed Brown ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 34928501fc72SJed Brown ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 34938501fc72SJed Brown ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 34948501fc72SJed Brown } 34958501fc72SJed Brown 3496e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3497efd51863SBarry Smith if (grid < snes->gridsequence) { 3498efd51863SBarry Smith DM fine; 3499efd51863SBarry Smith Vec xnew; 3500efd51863SBarry Smith Mat interp; 3501efd51863SBarry Smith 3502efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3503c5c77316SJed Brown if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 3504e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3505efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3506efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3507efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3508efd51863SBarry Smith x = xnew; 3509efd51863SBarry Smith 3510efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3511efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3512efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3513a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3514efd51863SBarry Smith } 3515efd51863SBarry Smith } 3516a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 35173a40ed3dSBarry Smith PetscFunctionReturn(0); 35189b94acceSBarry Smith } 35199b94acceSBarry Smith 35209b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 35219b94acceSBarry Smith 35224a2ae208SSatish Balay #undef __FUNCT__ 35234a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 352482bf6240SBarry Smith /*@C 35254b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 35269b94acceSBarry Smith 3527fee21e36SBarry Smith Collective on SNES 3528fee21e36SBarry Smith 3529c7afd0dbSLois Curfman McInnes Input Parameters: 3530c7afd0dbSLois Curfman McInnes + snes - the SNES context 3531454a90a3SBarry Smith - type - a known method 3532c7afd0dbSLois Curfman McInnes 3533c7afd0dbSLois Curfman McInnes Options Database Key: 3534454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3535c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3536ae12b187SLois Curfman McInnes 35379b94acceSBarry Smith Notes: 3538e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 35394b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3540c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 35414b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3542c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 35439b94acceSBarry Smith 3544ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3545ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3546ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3547ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3548ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3549ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3550ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3551ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3552ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3553b0a32e0cSBarry Smith appropriate method. 355436851e7fSLois Curfman McInnes 355536851e7fSLois Curfman McInnes Level: intermediate 3556a703fe33SLois Curfman McInnes 3557454a90a3SBarry Smith .keywords: SNES, set, type 3558435da068SBarry Smith 3559435da068SBarry Smith .seealso: SNESType, SNESCreate() 3560435da068SBarry Smith 35619b94acceSBarry Smith @*/ 35627087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 35639b94acceSBarry Smith { 3564dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3565ace3abfcSBarry Smith PetscBool match; 35663a40ed3dSBarry Smith 35673a40ed3dSBarry Smith PetscFunctionBegin; 35680700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35694482741eSBarry Smith PetscValidCharPointer(type,2); 357082bf6240SBarry Smith 35716831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 35720f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 357392ff6ae8SBarry Smith 35744b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3575e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 357675396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 3577b5c23020SJed Brown if (snes->ops->destroy) { 3578b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 3579b5c23020SJed Brown snes->ops->destroy = PETSC_NULL; 3580b5c23020SJed Brown } 358175396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 358275396ef9SLisandro Dalcin snes->ops->setup = 0; 358375396ef9SLisandro Dalcin snes->ops->solve = 0; 358475396ef9SLisandro Dalcin snes->ops->view = 0; 358575396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 358675396ef9SLisandro Dalcin snes->ops->destroy = 0; 358775396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 358875396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3589454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 359003bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 35919fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 35929fb22e1aSBarry Smith if (PetscAMSPublishAll) { 35939fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 35949fb22e1aSBarry Smith } 35959fb22e1aSBarry Smith #endif 35963a40ed3dSBarry Smith PetscFunctionReturn(0); 35979b94acceSBarry Smith } 35989b94acceSBarry Smith 3599a847f771SSatish Balay 36009b94acceSBarry Smith /* --------------------------------------------------------------------- */ 36014a2ae208SSatish Balay #undef __FUNCT__ 36024a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 360352baeb72SSatish Balay /*@ 36049b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3605f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 36069b94acceSBarry Smith 3607fee21e36SBarry Smith Not Collective 3608fee21e36SBarry Smith 360936851e7fSLois Curfman McInnes Level: advanced 361036851e7fSLois Curfman McInnes 36119b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 36129b94acceSBarry Smith 36139b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 36149b94acceSBarry Smith @*/ 36157087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 36169b94acceSBarry Smith { 3617dfbe8321SBarry Smith PetscErrorCode ierr; 361882bf6240SBarry Smith 36193a40ed3dSBarry Smith PetscFunctionBegin; 36201441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 36214c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 36223a40ed3dSBarry Smith PetscFunctionReturn(0); 36239b94acceSBarry Smith } 36249b94acceSBarry Smith 36254a2ae208SSatish Balay #undef __FUNCT__ 36264a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 36279b94acceSBarry Smith /*@C 36289a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 36299b94acceSBarry Smith 3630c7afd0dbSLois Curfman McInnes Not Collective 3631c7afd0dbSLois Curfman McInnes 36329b94acceSBarry Smith Input Parameter: 36334b0e389bSBarry Smith . snes - nonlinear solver context 36349b94acceSBarry Smith 36359b94acceSBarry Smith Output Parameter: 36363a7fca6bSBarry Smith . type - SNES method (a character string) 36379b94acceSBarry Smith 363836851e7fSLois Curfman McInnes Level: intermediate 363936851e7fSLois Curfman McInnes 3640454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 36419b94acceSBarry Smith @*/ 36427087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 36439b94acceSBarry Smith { 36443a40ed3dSBarry Smith PetscFunctionBegin; 36450700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36464482741eSBarry Smith PetscValidPointer(type,2); 36477adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 36483a40ed3dSBarry Smith PetscFunctionReturn(0); 36499b94acceSBarry Smith } 36509b94acceSBarry Smith 36514a2ae208SSatish Balay #undef __FUNCT__ 36524a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 365352baeb72SSatish Balay /*@ 36549b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3655c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 36569b94acceSBarry Smith 3657c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3658c7afd0dbSLois Curfman McInnes 36599b94acceSBarry Smith Input Parameter: 36609b94acceSBarry Smith . snes - the SNES context 36619b94acceSBarry Smith 36629b94acceSBarry Smith Output Parameter: 36639b94acceSBarry Smith . x - the solution 36649b94acceSBarry Smith 366570e92668SMatthew Knepley Level: intermediate 366636851e7fSLois Curfman McInnes 36679b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 36689b94acceSBarry Smith 366985385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 36709b94acceSBarry Smith @*/ 36717087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 36729b94acceSBarry Smith { 36733a40ed3dSBarry Smith PetscFunctionBegin; 36740700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36754482741eSBarry Smith PetscValidPointer(x,2); 367685385478SLisandro Dalcin *x = snes->vec_sol; 367770e92668SMatthew Knepley PetscFunctionReturn(0); 367870e92668SMatthew Knepley } 367970e92668SMatthew Knepley 368070e92668SMatthew Knepley #undef __FUNCT__ 36814a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 368252baeb72SSatish Balay /*@ 36839b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 36849b94acceSBarry Smith stored. 36859b94acceSBarry Smith 3686c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3687c7afd0dbSLois Curfman McInnes 36889b94acceSBarry Smith Input Parameter: 36899b94acceSBarry Smith . snes - the SNES context 36909b94acceSBarry Smith 36919b94acceSBarry Smith Output Parameter: 36929b94acceSBarry Smith . x - the solution update 36939b94acceSBarry Smith 369436851e7fSLois Curfman McInnes Level: advanced 369536851e7fSLois Curfman McInnes 36969b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 36979b94acceSBarry Smith 369885385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 36999b94acceSBarry Smith @*/ 37007087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 37019b94acceSBarry Smith { 37023a40ed3dSBarry Smith PetscFunctionBegin; 37030700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37044482741eSBarry Smith PetscValidPointer(x,2); 370585385478SLisandro Dalcin *x = snes->vec_sol_update; 37063a40ed3dSBarry Smith PetscFunctionReturn(0); 37079b94acceSBarry Smith } 37089b94acceSBarry Smith 37094a2ae208SSatish Balay #undef __FUNCT__ 37104a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 37119b94acceSBarry Smith /*@C 37123638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 37139b94acceSBarry Smith 3714a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 3715c7afd0dbSLois Curfman McInnes 37169b94acceSBarry Smith Input Parameter: 37179b94acceSBarry Smith . snes - the SNES context 37189b94acceSBarry Smith 37199b94acceSBarry Smith Output Parameter: 37207bf4e008SBarry Smith + r - the function (or PETSC_NULL) 372170e92668SMatthew Knepley . func - the function (or PETSC_NULL) 372270e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 37239b94acceSBarry Smith 372436851e7fSLois Curfman McInnes Level: advanced 372536851e7fSLois Curfman McInnes 3726a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 37279b94acceSBarry Smith 37284b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 37299b94acceSBarry Smith @*/ 37307087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 37319b94acceSBarry Smith { 3732a63bb30eSJed Brown PetscErrorCode ierr; 37336cab3a1bSJed Brown DM dm; 3734a63bb30eSJed Brown 37353a40ed3dSBarry Smith PetscFunctionBegin; 37360700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3737a63bb30eSJed Brown if (r) { 3738a63bb30eSJed Brown if (!snes->vec_func) { 3739a63bb30eSJed Brown if (snes->vec_rhs) { 3740a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 3741a63bb30eSJed Brown } else if (snes->vec_sol) { 3742a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 3743a63bb30eSJed Brown } else if (snes->dm) { 3744a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 3745a63bb30eSJed Brown } 3746a63bb30eSJed Brown } 3747a63bb30eSJed Brown *r = snes->vec_func; 3748a63bb30eSJed Brown } 37496cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 37506cab3a1bSJed Brown ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr); 37513a40ed3dSBarry Smith PetscFunctionReturn(0); 37529b94acceSBarry Smith } 37539b94acceSBarry Smith 3754c79ef259SPeter Brune /*@C 3755c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3756c79ef259SPeter Brune 3757c79ef259SPeter Brune Input Parameter: 3758c79ef259SPeter Brune . snes - the SNES context 3759c79ef259SPeter Brune 3760c79ef259SPeter Brune Output Parameter: 3761c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3762c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3763c79ef259SPeter Brune 3764c79ef259SPeter Brune Level: advanced 3765c79ef259SPeter Brune 3766c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3767c79ef259SPeter Brune 3768c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3769c79ef259SPeter Brune @*/ 3770c79ef259SPeter Brune 37714a2ae208SSatish Balay #undef __FUNCT__ 3772646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3773646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3774646217ecSPeter Brune { 37756cab3a1bSJed Brown PetscErrorCode ierr; 37766cab3a1bSJed Brown DM dm; 37776cab3a1bSJed Brown 3778646217ecSPeter Brune PetscFunctionBegin; 3779646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37806cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 37816cab3a1bSJed Brown ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr); 3782646217ecSPeter Brune PetscFunctionReturn(0); 3783646217ecSPeter Brune } 3784646217ecSPeter Brune 37854a2ae208SSatish Balay #undef __FUNCT__ 37864a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 37873c7409f5SSatish Balay /*@C 37883c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3789d850072dSLois Curfman McInnes SNES options in the database. 37903c7409f5SSatish Balay 37913f9fe445SBarry Smith Logically Collective on SNES 3792fee21e36SBarry Smith 3793c7afd0dbSLois Curfman McInnes Input Parameter: 3794c7afd0dbSLois Curfman McInnes + snes - the SNES context 3795c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3796c7afd0dbSLois Curfman McInnes 3797d850072dSLois Curfman McInnes Notes: 3798a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3799c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3800d850072dSLois Curfman McInnes 380136851e7fSLois Curfman McInnes Level: advanced 380236851e7fSLois Curfman McInnes 38033c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3804a86d99e1SLois Curfman McInnes 3805a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 38063c7409f5SSatish Balay @*/ 38077087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 38083c7409f5SSatish Balay { 3809dfbe8321SBarry Smith PetscErrorCode ierr; 38103c7409f5SSatish Balay 38113a40ed3dSBarry Smith PetscFunctionBegin; 38120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3813639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 38141cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 381594b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 38163a40ed3dSBarry Smith PetscFunctionReturn(0); 38173c7409f5SSatish Balay } 38183c7409f5SSatish Balay 38194a2ae208SSatish Balay #undef __FUNCT__ 38204a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 38213c7409f5SSatish Balay /*@C 3822f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3823d850072dSLois Curfman McInnes SNES options in the database. 38243c7409f5SSatish Balay 38253f9fe445SBarry Smith Logically Collective on SNES 3826fee21e36SBarry Smith 3827c7afd0dbSLois Curfman McInnes Input Parameters: 3828c7afd0dbSLois Curfman McInnes + snes - the SNES context 3829c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3830c7afd0dbSLois Curfman McInnes 3831d850072dSLois Curfman McInnes Notes: 3832a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3833c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3834d850072dSLois Curfman McInnes 383536851e7fSLois Curfman McInnes Level: advanced 383636851e7fSLois Curfman McInnes 38373c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3838a86d99e1SLois Curfman McInnes 3839a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 38403c7409f5SSatish Balay @*/ 38417087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 38423c7409f5SSatish Balay { 3843dfbe8321SBarry Smith PetscErrorCode ierr; 38443c7409f5SSatish Balay 38453a40ed3dSBarry Smith PetscFunctionBegin; 38460700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3847639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 38481cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 384994b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 38503a40ed3dSBarry Smith PetscFunctionReturn(0); 38513c7409f5SSatish Balay } 38523c7409f5SSatish Balay 38534a2ae208SSatish Balay #undef __FUNCT__ 38544a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 38559ab63eb5SSatish Balay /*@C 38563c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 38573c7409f5SSatish Balay SNES options in the database. 38583c7409f5SSatish Balay 3859c7afd0dbSLois Curfman McInnes Not Collective 3860c7afd0dbSLois Curfman McInnes 38613c7409f5SSatish Balay Input Parameter: 38623c7409f5SSatish Balay . snes - the SNES context 38633c7409f5SSatish Balay 38643c7409f5SSatish Balay Output Parameter: 38653c7409f5SSatish Balay . prefix - pointer to the prefix string used 38663c7409f5SSatish Balay 38674ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 38689ab63eb5SSatish Balay sufficient length to hold the prefix. 38699ab63eb5SSatish Balay 387036851e7fSLois Curfman McInnes Level: advanced 387136851e7fSLois Curfman McInnes 38723c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 3873a86d99e1SLois Curfman McInnes 3874a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 38753c7409f5SSatish Balay @*/ 38767087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 38773c7409f5SSatish Balay { 3878dfbe8321SBarry Smith PetscErrorCode ierr; 38793c7409f5SSatish Balay 38803a40ed3dSBarry Smith PetscFunctionBegin; 38810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3882639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 38833a40ed3dSBarry Smith PetscFunctionReturn(0); 38843c7409f5SSatish Balay } 38853c7409f5SSatish Balay 3886b2002411SLois Curfman McInnes 38874a2ae208SSatish Balay #undef __FUNCT__ 38884a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 38893cea93caSBarry Smith /*@C 38903cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 38913cea93caSBarry Smith 38927f6c08e0SMatthew Knepley Level: advanced 38933cea93caSBarry Smith @*/ 38947087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3895b2002411SLois Curfman McInnes { 3896e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3897dfbe8321SBarry Smith PetscErrorCode ierr; 3898b2002411SLois Curfman McInnes 3899b2002411SLois Curfman McInnes PetscFunctionBegin; 3900b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3901c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3902b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3903b2002411SLois Curfman McInnes } 3904da9b6338SBarry Smith 3905da9b6338SBarry Smith #undef __FUNCT__ 3906da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 39077087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3908da9b6338SBarry Smith { 3909dfbe8321SBarry Smith PetscErrorCode ierr; 391077431f27SBarry Smith PetscInt N,i,j; 3911da9b6338SBarry Smith Vec u,uh,fh; 3912da9b6338SBarry Smith PetscScalar value; 3913da9b6338SBarry Smith PetscReal norm; 3914da9b6338SBarry Smith 3915da9b6338SBarry Smith PetscFunctionBegin; 3916da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3917da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3918da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3919da9b6338SBarry Smith 3920da9b6338SBarry Smith /* currently only works for sequential */ 3921da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3922da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3923da9b6338SBarry Smith for (i=0; i<N; i++) { 3924da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 392577431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3926da9b6338SBarry Smith for (j=-10; j<11; j++) { 3927ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3928da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 39293ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3930da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 393177431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3932da9b6338SBarry Smith value = -value; 3933da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3934da9b6338SBarry Smith } 3935da9b6338SBarry Smith } 39366bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 39376bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 3938da9b6338SBarry Smith PetscFunctionReturn(0); 3939da9b6338SBarry Smith } 394071f87433Sdalcinl 394171f87433Sdalcinl #undef __FUNCT__ 3942fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 394371f87433Sdalcinl /*@ 3944fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 394571f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 394671f87433Sdalcinl Newton method. 394771f87433Sdalcinl 39483f9fe445SBarry Smith Logically Collective on SNES 394971f87433Sdalcinl 395071f87433Sdalcinl Input Parameters: 395171f87433Sdalcinl + snes - SNES context 395271f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 395371f87433Sdalcinl 395464ba62caSBarry Smith Options Database: 395564ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 395664ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 395764ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 395864ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 395964ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 396064ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 396164ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 396264ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 396364ba62caSBarry Smith 396471f87433Sdalcinl Notes: 396571f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 396671f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 396771f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 396871f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 396971f87433Sdalcinl solver. 397071f87433Sdalcinl 397171f87433Sdalcinl Level: advanced 397271f87433Sdalcinl 397371f87433Sdalcinl Reference: 397471f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 397571f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 397671f87433Sdalcinl 397771f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 397871f87433Sdalcinl 3979fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 398071f87433Sdalcinl @*/ 39817087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 398271f87433Sdalcinl { 398371f87433Sdalcinl PetscFunctionBegin; 39840700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3985acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 398671f87433Sdalcinl snes->ksp_ewconv = flag; 398771f87433Sdalcinl PetscFunctionReturn(0); 398871f87433Sdalcinl } 398971f87433Sdalcinl 399071f87433Sdalcinl #undef __FUNCT__ 3991fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 399271f87433Sdalcinl /*@ 3993fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 399471f87433Sdalcinl for computing relative tolerance for linear solvers within an 399571f87433Sdalcinl inexact Newton method. 399671f87433Sdalcinl 399771f87433Sdalcinl Not Collective 399871f87433Sdalcinl 399971f87433Sdalcinl Input Parameter: 400071f87433Sdalcinl . snes - SNES context 400171f87433Sdalcinl 400271f87433Sdalcinl Output Parameter: 400371f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 400471f87433Sdalcinl 400571f87433Sdalcinl Notes: 400671f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 400771f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 400871f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 400971f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 401071f87433Sdalcinl solver. 401171f87433Sdalcinl 401271f87433Sdalcinl Level: advanced 401371f87433Sdalcinl 401471f87433Sdalcinl Reference: 401571f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 401671f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 401771f87433Sdalcinl 401871f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 401971f87433Sdalcinl 4020fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 402171f87433Sdalcinl @*/ 40227087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 402371f87433Sdalcinl { 402471f87433Sdalcinl PetscFunctionBegin; 40250700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 402671f87433Sdalcinl PetscValidPointer(flag,2); 402771f87433Sdalcinl *flag = snes->ksp_ewconv; 402871f87433Sdalcinl PetscFunctionReturn(0); 402971f87433Sdalcinl } 403071f87433Sdalcinl 403171f87433Sdalcinl #undef __FUNCT__ 4032fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 403371f87433Sdalcinl /*@ 4034fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 403571f87433Sdalcinl convergence criteria for the linear solvers within an inexact 403671f87433Sdalcinl Newton method. 403771f87433Sdalcinl 40383f9fe445SBarry Smith Logically Collective on SNES 403971f87433Sdalcinl 404071f87433Sdalcinl Input Parameters: 404171f87433Sdalcinl + snes - SNES context 404271f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 404371f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 404471f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 404571f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 404671f87433Sdalcinl (0 <= gamma2 <= 1) 404771f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 404871f87433Sdalcinl . alpha2 - power for safeguard 404971f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 405071f87433Sdalcinl 405171f87433Sdalcinl Note: 405271f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 405371f87433Sdalcinl 405471f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 405571f87433Sdalcinl 405671f87433Sdalcinl Level: advanced 405771f87433Sdalcinl 405871f87433Sdalcinl Reference: 405971f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 406071f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 406171f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 406271f87433Sdalcinl 406371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 406471f87433Sdalcinl 4065fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 406671f87433Sdalcinl @*/ 40677087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 406871f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 406971f87433Sdalcinl { 4070fa9f3622SBarry Smith SNESKSPEW *kctx; 407171f87433Sdalcinl PetscFunctionBegin; 40720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4073fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4074e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 4075c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 4076c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 4077c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 4078c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 4079c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 4080c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 4081c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 408271f87433Sdalcinl 408371f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 408471f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 408571f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 408671f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 408771f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 408871f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 408971f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 409071f87433Sdalcinl 409171f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 4092e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 409371f87433Sdalcinl } 409471f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 4095e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 409671f87433Sdalcinl } 409771f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 4098e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 409971f87433Sdalcinl } 410071f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 4101e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 410271f87433Sdalcinl } 410371f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 4104e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 410571f87433Sdalcinl } 410671f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 4107e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 410871f87433Sdalcinl } 410971f87433Sdalcinl PetscFunctionReturn(0); 411071f87433Sdalcinl } 411171f87433Sdalcinl 411271f87433Sdalcinl #undef __FUNCT__ 4113fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 411471f87433Sdalcinl /*@ 4115fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 411671f87433Sdalcinl convergence criteria for the linear solvers within an inexact 411771f87433Sdalcinl Newton method. 411871f87433Sdalcinl 411971f87433Sdalcinl Not Collective 412071f87433Sdalcinl 412171f87433Sdalcinl Input Parameters: 412271f87433Sdalcinl snes - SNES context 412371f87433Sdalcinl 412471f87433Sdalcinl Output Parameters: 412571f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 412671f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 412771f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 412871f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 412971f87433Sdalcinl (0 <= gamma2 <= 1) 413071f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 413171f87433Sdalcinl . alpha2 - power for safeguard 413271f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 413371f87433Sdalcinl 413471f87433Sdalcinl Level: advanced 413571f87433Sdalcinl 413671f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 413771f87433Sdalcinl 4138fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 413971f87433Sdalcinl @*/ 41407087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 414171f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 414271f87433Sdalcinl { 4143fa9f3622SBarry Smith SNESKSPEW *kctx; 414471f87433Sdalcinl PetscFunctionBegin; 41450700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4146fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4147e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 414871f87433Sdalcinl if(version) *version = kctx->version; 414971f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 415071f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 415171f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 415271f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 415371f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 415471f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 415571f87433Sdalcinl PetscFunctionReturn(0); 415671f87433Sdalcinl } 415771f87433Sdalcinl 415871f87433Sdalcinl #undef __FUNCT__ 4159fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 4160fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 416171f87433Sdalcinl { 416271f87433Sdalcinl PetscErrorCode ierr; 4163fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 416471f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 416571f87433Sdalcinl 416671f87433Sdalcinl PetscFunctionBegin; 4167e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 416871f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 416971f87433Sdalcinl rtol = kctx->rtol_0; 417071f87433Sdalcinl } else { 417171f87433Sdalcinl if (kctx->version == 1) { 417271f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 417371f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 417471f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 417571f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 417671f87433Sdalcinl } else if (kctx->version == 2) { 417771f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 417871f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 417971f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 418071f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 418171f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 418271f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 418371f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 418471f87433Sdalcinl stol = PetscMax(rtol,stol); 418571f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 418671f87433Sdalcinl /* safeguard: avoid oversolving */ 418771f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 418871f87433Sdalcinl stol = PetscMax(rtol,stol); 418971f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 4190e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 419171f87433Sdalcinl } 419271f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 419371f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 419471f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 419571f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 419671f87433Sdalcinl PetscFunctionReturn(0); 419771f87433Sdalcinl } 419871f87433Sdalcinl 419971f87433Sdalcinl #undef __FUNCT__ 4200fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 4201fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 420271f87433Sdalcinl { 420371f87433Sdalcinl PetscErrorCode ierr; 4204fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 420571f87433Sdalcinl PCSide pcside; 420671f87433Sdalcinl Vec lres; 420771f87433Sdalcinl 420871f87433Sdalcinl PetscFunctionBegin; 4209e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 421071f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 421171f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 421271f87433Sdalcinl if (kctx->version == 1) { 4213b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 421471f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 421571f87433Sdalcinl /* KSP residual is true linear residual */ 421671f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 421771f87433Sdalcinl } else { 421871f87433Sdalcinl /* KSP residual is preconditioned residual */ 421971f87433Sdalcinl /* compute true linear residual norm */ 422071f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 422171f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 422271f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 422371f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 42246bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 422571f87433Sdalcinl } 422671f87433Sdalcinl } 422771f87433Sdalcinl PetscFunctionReturn(0); 422871f87433Sdalcinl } 422971f87433Sdalcinl 423071f87433Sdalcinl #undef __FUNCT__ 423171f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 423271f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 423371f87433Sdalcinl { 423471f87433Sdalcinl PetscErrorCode ierr; 423571f87433Sdalcinl 423671f87433Sdalcinl PetscFunctionBegin; 4237fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 423871f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 4239fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 424071f87433Sdalcinl PetscFunctionReturn(0); 424171f87433Sdalcinl } 42426c699258SBarry Smith 42436c699258SBarry Smith #undef __FUNCT__ 42446c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 42456c699258SBarry Smith /*@ 42466c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 42476c699258SBarry Smith 42483f9fe445SBarry Smith Logically Collective on SNES 42496c699258SBarry Smith 42506c699258SBarry Smith Input Parameters: 42516c699258SBarry Smith + snes - the preconditioner context 42526c699258SBarry Smith - dm - the dm 42536c699258SBarry Smith 42546c699258SBarry Smith Level: intermediate 42556c699258SBarry Smith 42566c699258SBarry Smith 42576c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 42586c699258SBarry Smith @*/ 42597087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 42606c699258SBarry Smith { 42616c699258SBarry Smith PetscErrorCode ierr; 4262345fed2cSBarry Smith KSP ksp; 42636cab3a1bSJed Brown SNESDM sdm; 42646c699258SBarry Smith 42656c699258SBarry Smith PetscFunctionBegin; 42660700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4267d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 42686cab3a1bSJed Brown if (snes->dm) { /* Move the SNESDM context over to the new DM unless the new DM already has one */ 42696cab3a1bSJed Brown PetscContainer oldcontainer,container; 42706cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 42716cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr); 42726cab3a1bSJed Brown if (oldcontainer && !container) { 42736cab3a1bSJed Brown ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr); 42746cab3a1bSJed Brown ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr); 42756cab3a1bSJed Brown if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */ 42766cab3a1bSJed Brown sdm->originaldm = dm; 42776cab3a1bSJed Brown } 42786cab3a1bSJed Brown } 42796bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 42806cab3a1bSJed Brown } 42816c699258SBarry Smith snes->dm = dm; 4282345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4283345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4284f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 42852c155ee1SBarry Smith if (snes->pc) { 42862c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 42872c155ee1SBarry Smith } 42886c699258SBarry Smith PetscFunctionReturn(0); 42896c699258SBarry Smith } 42906c699258SBarry Smith 42916c699258SBarry Smith #undef __FUNCT__ 42926c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 42936c699258SBarry Smith /*@ 42946c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 42956c699258SBarry Smith 42963f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 42976c699258SBarry Smith 42986c699258SBarry Smith Input Parameter: 42996c699258SBarry Smith . snes - the preconditioner context 43006c699258SBarry Smith 43016c699258SBarry Smith Output Parameter: 43026c699258SBarry Smith . dm - the dm 43036c699258SBarry Smith 43046c699258SBarry Smith Level: intermediate 43056c699258SBarry Smith 43066c699258SBarry Smith 43076c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 43086c699258SBarry Smith @*/ 43097087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 43106c699258SBarry Smith { 43116cab3a1bSJed Brown PetscErrorCode ierr; 43126cab3a1bSJed Brown 43136c699258SBarry Smith PetscFunctionBegin; 43140700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 43156cab3a1bSJed Brown if (!snes->dm) { 43166cab3a1bSJed Brown ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr); 43176cab3a1bSJed Brown } 43186c699258SBarry Smith *dm = snes->dm; 43196c699258SBarry Smith PetscFunctionReturn(0); 43206c699258SBarry Smith } 43210807856dSBarry Smith 432231823bd8SMatthew G Knepley #undef __FUNCT__ 432331823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 432431823bd8SMatthew G Knepley /*@ 4325fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 432631823bd8SMatthew G Knepley 432731823bd8SMatthew G Knepley Collective on SNES 432831823bd8SMatthew G Knepley 432931823bd8SMatthew G Knepley Input Parameters: 433031823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 433131823bd8SMatthew G Knepley - pc - the preconditioner object 433231823bd8SMatthew G Knepley 433331823bd8SMatthew G Knepley Notes: 433431823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 433531823bd8SMatthew G Knepley to configure it using the API). 433631823bd8SMatthew G Knepley 433731823bd8SMatthew G Knepley Level: developer 433831823bd8SMatthew G Knepley 433931823bd8SMatthew G Knepley .keywords: SNES, set, precondition 434031823bd8SMatthew G Knepley .seealso: SNESGetPC() 434131823bd8SMatthew G Knepley @*/ 434231823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 434331823bd8SMatthew G Knepley { 434431823bd8SMatthew G Knepley PetscErrorCode ierr; 434531823bd8SMatthew G Knepley 434631823bd8SMatthew G Knepley PetscFunctionBegin; 434731823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 434831823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 434931823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 435031823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4351bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 435231823bd8SMatthew G Knepley snes->pc = pc; 435331823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 435431823bd8SMatthew G Knepley PetscFunctionReturn(0); 435531823bd8SMatthew G Knepley } 435631823bd8SMatthew G Knepley 435731823bd8SMatthew G Knepley #undef __FUNCT__ 435831823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 435931823bd8SMatthew G Knepley /*@ 4360fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 436131823bd8SMatthew G Knepley 436231823bd8SMatthew G Knepley Not Collective 436331823bd8SMatthew G Knepley 436431823bd8SMatthew G Knepley Input Parameter: 436531823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 436631823bd8SMatthew G Knepley 436731823bd8SMatthew G Knepley Output Parameter: 436831823bd8SMatthew G Knepley . pc - preconditioner context 436931823bd8SMatthew G Knepley 437031823bd8SMatthew G Knepley Level: developer 437131823bd8SMatthew G Knepley 437231823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 437331823bd8SMatthew G Knepley .seealso: SNESSetPC() 437431823bd8SMatthew G Knepley @*/ 437531823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 437631823bd8SMatthew G Knepley { 437731823bd8SMatthew G Knepley PetscErrorCode ierr; 437831823bd8SMatthew G Knepley 437931823bd8SMatthew G Knepley PetscFunctionBegin; 438031823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 438131823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 438231823bd8SMatthew G Knepley if (!snes->pc) { 438331823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr); 43844a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr); 438531823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 438631823bd8SMatthew G Knepley } 438731823bd8SMatthew G Knepley *pc = snes->pc; 438831823bd8SMatthew G Knepley PetscFunctionReturn(0); 438931823bd8SMatthew G Knepley } 439031823bd8SMatthew G Knepley 43919e764e56SPeter Brune #undef __FUNCT__ 4392f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch" 43939e764e56SPeter Brune /*@ 4394f1c6b773SPeter Brune SNESSetSNESLineSearch - Sets the linesearch. 43959e764e56SPeter Brune 43969e764e56SPeter Brune Collective on SNES 43979e764e56SPeter Brune 43989e764e56SPeter Brune Input Parameters: 43999e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 44009e764e56SPeter Brune - linesearch - the linesearch object 44019e764e56SPeter Brune 44029e764e56SPeter Brune Notes: 4403f1c6b773SPeter Brune Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example, 44049e764e56SPeter Brune to configure it using the API). 44059e764e56SPeter Brune 44069e764e56SPeter Brune Level: developer 44079e764e56SPeter Brune 44089e764e56SPeter Brune .keywords: SNES, set, linesearch 4409f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch() 44109e764e56SPeter Brune @*/ 4411f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch) 44129e764e56SPeter Brune { 44139e764e56SPeter Brune PetscErrorCode ierr; 44149e764e56SPeter Brune 44159e764e56SPeter Brune PetscFunctionBegin; 44169e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4417f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 44189e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 44199e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 4420f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 44219e764e56SPeter Brune snes->linesearch = linesearch; 44229e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 44239e764e56SPeter Brune PetscFunctionReturn(0); 44249e764e56SPeter Brune } 44259e764e56SPeter Brune 44269e764e56SPeter Brune #undef __FUNCT__ 4427f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch" 4428ea5d4fccSPeter Brune /*@C 4429f1c6b773SPeter Brune SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch(). 44309e764e56SPeter Brune 44319e764e56SPeter Brune Not Collective 44329e764e56SPeter Brune 44339e764e56SPeter Brune Input Parameter: 44349e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 44359e764e56SPeter Brune 44369e764e56SPeter Brune Output Parameter: 44379e764e56SPeter Brune . linesearch - linesearch context 44389e764e56SPeter Brune 44399e764e56SPeter Brune Level: developer 44409e764e56SPeter Brune 44419e764e56SPeter Brune .keywords: SNES, get, linesearch 4442f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch() 44439e764e56SPeter Brune @*/ 4444f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch) 44459e764e56SPeter Brune { 44469e764e56SPeter Brune PetscErrorCode ierr; 44479e764e56SPeter Brune const char *optionsprefix; 44489e764e56SPeter Brune 44499e764e56SPeter Brune PetscFunctionBegin; 44509e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 44519e764e56SPeter Brune PetscValidPointer(linesearch, 2); 44529e764e56SPeter Brune if (!snes->linesearch) { 44539e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 4454f1c6b773SPeter Brune ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr); 4455f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 4456b1dca40bSPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 44579e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 44589e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 44599e764e56SPeter Brune } 44609e764e56SPeter Brune *linesearch = snes->linesearch; 44619e764e56SPeter Brune PetscFunctionReturn(0); 44629e764e56SPeter Brune } 44639e764e56SPeter Brune 446469b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4465c6db04a5SJed Brown #include <mex.h> 446669b4f73cSBarry Smith 44678f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 44688f6e6473SBarry Smith 44690807856dSBarry Smith #undef __FUNCT__ 44700807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 44710807856dSBarry Smith /* 44720807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 44730807856dSBarry Smith SNESSetFunctionMatlab(). 44740807856dSBarry Smith 44750807856dSBarry Smith Collective on SNES 44760807856dSBarry Smith 44770807856dSBarry Smith Input Parameters: 44780807856dSBarry Smith + snes - the SNES context 44790807856dSBarry Smith - x - input vector 44800807856dSBarry Smith 44810807856dSBarry Smith Output Parameter: 44820807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 44830807856dSBarry Smith 44840807856dSBarry Smith Notes: 44850807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 44860807856dSBarry Smith implementations, so most users would not generally call this routine 44870807856dSBarry Smith themselves. 44880807856dSBarry Smith 44890807856dSBarry Smith Level: developer 44900807856dSBarry Smith 44910807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 44920807856dSBarry Smith 44930807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 449461b2408cSBarry Smith */ 44957087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 44960807856dSBarry Smith { 4497e650e774SBarry Smith PetscErrorCode ierr; 44988f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 44998f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 45008f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 450191621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 4502e650e774SBarry Smith 45030807856dSBarry Smith PetscFunctionBegin; 45040807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 45050807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 45060807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 45070807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 45080807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 45090807856dSBarry Smith 45100807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 4511e650e774SBarry Smith 451291621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4513e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4514e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 451591621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 451691621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 451791621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 45188f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 45198f6e6473SBarry Smith prhs[4] = sctx->ctx; 4520b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 4521e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4522e650e774SBarry Smith mxDestroyArray(prhs[0]); 4523e650e774SBarry Smith mxDestroyArray(prhs[1]); 4524e650e774SBarry Smith mxDestroyArray(prhs[2]); 45258f6e6473SBarry Smith mxDestroyArray(prhs[3]); 4526e650e774SBarry Smith mxDestroyArray(plhs[0]); 45270807856dSBarry Smith PetscFunctionReturn(0); 45280807856dSBarry Smith } 45290807856dSBarry Smith 45300807856dSBarry Smith 45310807856dSBarry Smith #undef __FUNCT__ 45320807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 453361b2408cSBarry Smith /* 45340807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 45350807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4536e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 45370807856dSBarry Smith 45380807856dSBarry Smith Logically Collective on SNES 45390807856dSBarry Smith 45400807856dSBarry Smith Input Parameters: 45410807856dSBarry Smith + snes - the SNES context 45420807856dSBarry Smith . r - vector to store function value 45430807856dSBarry Smith - func - function evaluation routine 45440807856dSBarry Smith 45450807856dSBarry Smith Calling sequence of func: 454661b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 45470807856dSBarry Smith 45480807856dSBarry Smith 45490807856dSBarry Smith Notes: 45500807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 45510807856dSBarry Smith $ f'(x) x = -f(x), 45520807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 45530807856dSBarry Smith 45540807856dSBarry Smith Level: beginner 45550807856dSBarry Smith 45560807856dSBarry Smith .keywords: SNES, nonlinear, set, function 45570807856dSBarry Smith 45580807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 455961b2408cSBarry Smith */ 45607087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 45610807856dSBarry Smith { 45620807856dSBarry Smith PetscErrorCode ierr; 45638f6e6473SBarry Smith SNESMatlabContext *sctx; 45640807856dSBarry Smith 45650807856dSBarry Smith PetscFunctionBegin; 45668f6e6473SBarry Smith /* currently sctx is memory bleed */ 45678f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 45688f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 45698f6e6473SBarry Smith /* 45708f6e6473SBarry Smith This should work, but it doesn't 45718f6e6473SBarry Smith sctx->ctx = ctx; 45728f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 45738f6e6473SBarry Smith */ 45748f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 45758f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 45760807856dSBarry Smith PetscFunctionReturn(0); 45770807856dSBarry Smith } 457869b4f73cSBarry Smith 457961b2408cSBarry Smith #undef __FUNCT__ 458061b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 458161b2408cSBarry Smith /* 458261b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 458361b2408cSBarry Smith SNESSetJacobianMatlab(). 458461b2408cSBarry Smith 458561b2408cSBarry Smith Collective on SNES 458661b2408cSBarry Smith 458761b2408cSBarry Smith Input Parameters: 458861b2408cSBarry Smith + snes - the SNES context 458961b2408cSBarry Smith . x - input vector 459061b2408cSBarry Smith . A, B - the matrices 459161b2408cSBarry Smith - ctx - user context 459261b2408cSBarry Smith 459361b2408cSBarry Smith Output Parameter: 459461b2408cSBarry Smith . flag - structure of the matrix 459561b2408cSBarry Smith 459661b2408cSBarry Smith Level: developer 459761b2408cSBarry Smith 459861b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 459961b2408cSBarry Smith 460061b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 460161b2408cSBarry Smith @*/ 46027087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 460361b2408cSBarry Smith { 460461b2408cSBarry Smith PetscErrorCode ierr; 460561b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 460661b2408cSBarry Smith int nlhs = 2,nrhs = 6; 460761b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 460861b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 460961b2408cSBarry Smith 461061b2408cSBarry Smith PetscFunctionBegin; 461161b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 461261b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 461361b2408cSBarry Smith 461461b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 461561b2408cSBarry Smith 461661b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 461761b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 461861b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 461961b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 462061b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 462161b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 462261b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 462361b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 462461b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 462561b2408cSBarry Smith prhs[5] = sctx->ctx; 4626b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 462761b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 462861b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 462961b2408cSBarry Smith mxDestroyArray(prhs[0]); 463061b2408cSBarry Smith mxDestroyArray(prhs[1]); 463161b2408cSBarry Smith mxDestroyArray(prhs[2]); 463261b2408cSBarry Smith mxDestroyArray(prhs[3]); 463361b2408cSBarry Smith mxDestroyArray(prhs[4]); 463461b2408cSBarry Smith mxDestroyArray(plhs[0]); 463561b2408cSBarry Smith mxDestroyArray(plhs[1]); 463661b2408cSBarry Smith PetscFunctionReturn(0); 463761b2408cSBarry Smith } 463861b2408cSBarry Smith 463961b2408cSBarry Smith 464061b2408cSBarry Smith #undef __FUNCT__ 464161b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 464261b2408cSBarry Smith /* 464361b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 464461b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4645e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 464661b2408cSBarry Smith 464761b2408cSBarry Smith Logically Collective on SNES 464861b2408cSBarry Smith 464961b2408cSBarry Smith Input Parameters: 465061b2408cSBarry Smith + snes - the SNES context 465161b2408cSBarry Smith . A,B - Jacobian matrices 465261b2408cSBarry Smith . func - function evaluation routine 465361b2408cSBarry Smith - ctx - user context 465461b2408cSBarry Smith 465561b2408cSBarry Smith Calling sequence of func: 465661b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 465761b2408cSBarry Smith 465861b2408cSBarry Smith 465961b2408cSBarry Smith Level: developer 466061b2408cSBarry Smith 466161b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 466261b2408cSBarry Smith 466361b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 466461b2408cSBarry Smith */ 46657087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 466661b2408cSBarry Smith { 466761b2408cSBarry Smith PetscErrorCode ierr; 466861b2408cSBarry Smith SNESMatlabContext *sctx; 466961b2408cSBarry Smith 467061b2408cSBarry Smith PetscFunctionBegin; 467161b2408cSBarry Smith /* currently sctx is memory bleed */ 467261b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 467361b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 467461b2408cSBarry Smith /* 467561b2408cSBarry Smith This should work, but it doesn't 467661b2408cSBarry Smith sctx->ctx = ctx; 467761b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 467861b2408cSBarry Smith */ 467961b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 468061b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 468161b2408cSBarry Smith PetscFunctionReturn(0); 468261b2408cSBarry Smith } 468369b4f73cSBarry Smith 4684f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4685f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4686f9eb7ae2SShri Abhyankar /* 4687f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4688f9eb7ae2SShri Abhyankar 4689f9eb7ae2SShri Abhyankar Collective on SNES 4690f9eb7ae2SShri Abhyankar 4691f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4692f9eb7ae2SShri Abhyankar @*/ 46937087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4694f9eb7ae2SShri Abhyankar { 4695f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 469648f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4697f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4698f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4699f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4700f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4701f9eb7ae2SShri Abhyankar 4702f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4703f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4704f9eb7ae2SShri Abhyankar 4705f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4706f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4707f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4708f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4709f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4710f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4711f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4712f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4713f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4714f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4715f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4716f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4717f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4718f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4719f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4720f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4721f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4722f9eb7ae2SShri Abhyankar } 4723f9eb7ae2SShri Abhyankar 4724f9eb7ae2SShri Abhyankar 4725f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4726f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4727f9eb7ae2SShri Abhyankar /* 4728e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4729f9eb7ae2SShri Abhyankar 4730f9eb7ae2SShri Abhyankar Level: developer 4731f9eb7ae2SShri Abhyankar 4732f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4733f9eb7ae2SShri Abhyankar 4734f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4735f9eb7ae2SShri Abhyankar */ 47367087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4737f9eb7ae2SShri Abhyankar { 4738f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4739f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4740f9eb7ae2SShri Abhyankar 4741f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4742f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4743f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4744f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4745f9eb7ae2SShri Abhyankar /* 4746f9eb7ae2SShri Abhyankar This should work, but it doesn't 4747f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4748f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4749f9eb7ae2SShri Abhyankar */ 4750f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4751f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4752f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4753f9eb7ae2SShri Abhyankar } 4754f9eb7ae2SShri Abhyankar 475569b4f73cSBarry Smith #endif 4756