19b94acceSBarry Smith 2c6db04a5SJed Brown #include <private/snesimpl.h> /*I "petscsnes.h" I*/ 36cab3a1bSJed Brown #include <petscdmshell.h> /*I "petscdmshell.h" I*/ 49b94acceSBarry Smith 5ace3abfcSBarry Smith PetscBool SNESRegisterAllCalled = PETSC_FALSE; 68ba1e511SMatthew Knepley PetscFList SNESList = PETSC_NULL; 78ba1e511SMatthew Knepley 88ba1e511SMatthew Knepley /* Logging support */ 97087cfbeSBarry Smith PetscClassId SNES_CLASSID; 10701cf23dSPeter Brune PetscLogEvent SNES_Solve, SNES_LineSearch, 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 16cab2e9ccSBarry Smith */ 17cab2e9ccSBarry Smith PetscErrorCode SNESDMComputeJacobian(SNES snes,Vec X,Mat *J,Mat *B,MatStructure *flag,void *ptr) 18cab2e9ccSBarry Smith { 19cab2e9ccSBarry Smith PetscErrorCode ierr; 20cab2e9ccSBarry Smith DM dm; 21cab2e9ccSBarry Smith 22cab2e9ccSBarry Smith PetscFunctionBegin; 23cab2e9ccSBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 24cab2e9ccSBarry Smith ierr = DMComputeJacobian(dm,X,*J,*B,flag);CHKERRQ(ierr); 25cab2e9ccSBarry Smith PetscFunctionReturn(0); 26cab2e9ccSBarry Smith } 27cab2e9ccSBarry Smith 28cab2e9ccSBarry Smith #undef __FUNCT__ 29e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged" 30e113a28aSBarry Smith /*@ 31e113a28aSBarry Smith SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged. 32e113a28aSBarry Smith 333f9fe445SBarry Smith Logically Collective on SNES 34e113a28aSBarry Smith 35e113a28aSBarry Smith Input Parameters: 36e113a28aSBarry Smith + snes - iterative context obtained from SNESCreate() 37e113a28aSBarry Smith - flg - PETSC_TRUE indicates you want the error generated 38e113a28aSBarry Smith 39e113a28aSBarry Smith Options database keys: 40e113a28aSBarry Smith . -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false) 41e113a28aSBarry Smith 42e113a28aSBarry Smith Level: intermediate 43e113a28aSBarry Smith 44e113a28aSBarry Smith Notes: 45e113a28aSBarry Smith Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve() 46e113a28aSBarry Smith to determine if it has converged. 47e113a28aSBarry Smith 48e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 49e113a28aSBarry Smith 50e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 51e113a28aSBarry Smith @*/ 527087cfbeSBarry Smith PetscErrorCode SNESSetErrorIfNotConverged(SNES snes,PetscBool flg) 53e113a28aSBarry Smith { 54e113a28aSBarry Smith PetscFunctionBegin; 55e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 56acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flg,2); 57e113a28aSBarry Smith snes->errorifnotconverged = flg; 58dd568438SSatish Balay 59e113a28aSBarry Smith PetscFunctionReturn(0); 60e113a28aSBarry Smith } 61e113a28aSBarry Smith 62e113a28aSBarry Smith #undef __FUNCT__ 63e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged" 64e113a28aSBarry Smith /*@ 65e113a28aSBarry Smith SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge? 66e113a28aSBarry Smith 67e113a28aSBarry Smith Not Collective 68e113a28aSBarry Smith 69e113a28aSBarry Smith Input Parameter: 70e113a28aSBarry Smith . snes - iterative context obtained from SNESCreate() 71e113a28aSBarry Smith 72e113a28aSBarry Smith Output Parameter: 73e113a28aSBarry Smith . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE 74e113a28aSBarry Smith 75e113a28aSBarry Smith Level: intermediate 76e113a28aSBarry Smith 77e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 78e113a28aSBarry Smith 79e113a28aSBarry Smith .seealso: SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 80e113a28aSBarry Smith @*/ 817087cfbeSBarry Smith PetscErrorCode SNESGetErrorIfNotConverged(SNES snes,PetscBool *flag) 82e113a28aSBarry Smith { 83e113a28aSBarry Smith PetscFunctionBegin; 84e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 85e113a28aSBarry Smith PetscValidPointer(flag,2); 86e113a28aSBarry Smith *flag = snes->errorifnotconverged; 87e113a28aSBarry Smith PetscFunctionReturn(0); 88e113a28aSBarry Smith } 89e113a28aSBarry Smith 90e113a28aSBarry Smith #undef __FUNCT__ 914936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError" 92e725d27bSBarry Smith /*@ 934936397dSBarry Smith SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not 944936397dSBarry Smith in the functions domain. For example, negative pressure. 954936397dSBarry Smith 963f9fe445SBarry Smith Logically Collective on SNES 974936397dSBarry Smith 984936397dSBarry Smith Input Parameters: 996a388c36SPeter Brune . snes - the SNES context 1004936397dSBarry Smith 10128529972SSatish Balay Level: advanced 1024936397dSBarry Smith 1034936397dSBarry Smith .keywords: SNES, view 1044936397dSBarry Smith 1054936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction() 1064936397dSBarry Smith @*/ 1077087cfbeSBarry Smith PetscErrorCode SNESSetFunctionDomainError(SNES snes) 1084936397dSBarry Smith { 1094936397dSBarry Smith PetscFunctionBegin; 1100700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1114936397dSBarry Smith snes->domainerror = PETSC_TRUE; 1124936397dSBarry Smith PetscFunctionReturn(0); 1134936397dSBarry Smith } 1144936397dSBarry Smith 1156a388c36SPeter Brune 1166a388c36SPeter Brune #undef __FUNCT__ 1176a388c36SPeter Brune #define __FUNCT__ "SNESGetFunctionDomainError" 1186a388c36SPeter Brune /*@ 119c77b2880SPeter Brune SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction; 1206a388c36SPeter Brune 1216a388c36SPeter Brune Logically Collective on SNES 1226a388c36SPeter Brune 1236a388c36SPeter Brune Input Parameters: 1246a388c36SPeter Brune . snes - the SNES context 1256a388c36SPeter Brune 1266a388c36SPeter Brune Output Parameters: 1276a388c36SPeter Brune . domainerror Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise. 1286a388c36SPeter Brune 1296a388c36SPeter Brune Level: advanced 1306a388c36SPeter Brune 1316a388c36SPeter Brune .keywords: SNES, view 1326a388c36SPeter Brune 1336a388c36SPeter Brune .seealso: SNESSetFunctionDomainError, SNESComputeFunction() 1346a388c36SPeter Brune @*/ 1356a388c36SPeter Brune PetscErrorCode SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror) 1366a388c36SPeter Brune { 1376a388c36SPeter Brune PetscFunctionBegin; 1386a388c36SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1396a388c36SPeter Brune PetscValidPointer(domainerror, 2); 1406a388c36SPeter Brune *domainerror = snes->domainerror; 1416a388c36SPeter Brune PetscFunctionReturn(0); 1426a388c36SPeter Brune } 1436a388c36SPeter Brune 1446a388c36SPeter Brune 1454936397dSBarry Smith #undef __FUNCT__ 1464a2ae208SSatish Balay #define __FUNCT__ "SNESView" 1477e2c5f70SBarry Smith /*@C 1489b94acceSBarry Smith SNESView - Prints the SNES data structure. 1499b94acceSBarry Smith 1504c49b128SBarry Smith Collective on SNES 151fee21e36SBarry Smith 152c7afd0dbSLois Curfman McInnes Input Parameters: 153c7afd0dbSLois Curfman McInnes + SNES - the SNES context 154c7afd0dbSLois Curfman McInnes - viewer - visualization context 155c7afd0dbSLois Curfman McInnes 1569b94acceSBarry Smith Options Database Key: 157c8a8ba5cSLois Curfman McInnes . -snes_view - Calls SNESView() at end of SNESSolve() 1589b94acceSBarry Smith 1599b94acceSBarry Smith Notes: 1609b94acceSBarry Smith The available visualization contexts include 161b0a32e0cSBarry Smith + PETSC_VIEWER_STDOUT_SELF - standard output (default) 162b0a32e0cSBarry Smith - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 163c8a8ba5cSLois Curfman McInnes output where only the first processor opens 164c8a8ba5cSLois Curfman McInnes the file. All other processors send their 165c8a8ba5cSLois Curfman McInnes data to the first processor to print. 1669b94acceSBarry Smith 1673e081fefSLois Curfman McInnes The user can open an alternative visualization context with 168b0a32e0cSBarry Smith PetscViewerASCIIOpen() - output to a specified file. 1699b94acceSBarry Smith 17036851e7fSLois Curfman McInnes Level: beginner 17136851e7fSLois Curfman McInnes 1729b94acceSBarry Smith .keywords: SNES, view 1739b94acceSBarry Smith 174b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen() 1759b94acceSBarry Smith @*/ 1767087cfbeSBarry Smith PetscErrorCode SNESView(SNES snes,PetscViewer viewer) 1779b94acceSBarry Smith { 178fa9f3622SBarry Smith SNESKSPEW *kctx; 179dfbe8321SBarry Smith PetscErrorCode ierr; 18094b7f48cSBarry Smith KSP ksp; 181ace3abfcSBarry Smith PetscBool iascii,isstring; 1829b94acceSBarry Smith 1833a40ed3dSBarry Smith PetscFunctionBegin; 1840700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1853050cee2SBarry Smith if (!viewer) { 1867adad957SLisandro Dalcin ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 1873050cee2SBarry Smith } 1880700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 189c9780b6fSBarry Smith PetscCheckSameComm(snes,1,viewer,2); 19074679c65SBarry Smith 1912692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1922692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 19332077d6dSBarry Smith if (iascii) { 194317d6ea6SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr); 195e7788613SBarry Smith if (snes->ops->view) { 196b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 197e7788613SBarry Smith ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 198b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1990ef38995SBarry Smith } 20077431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr); 201a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%G, absolute=%G, solution=%G\n", 20270441072SBarry Smith snes->rtol,snes->abstol,snes->xtol);CHKERRQ(ierr); 20377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr); 20477431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr); 2059b94acceSBarry Smith if (snes->ksp_ewconv) { 206fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 2079b94acceSBarry Smith if (kctx) { 20877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr); 209a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr); 210a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr); 2119b94acceSBarry Smith } 2129b94acceSBarry Smith } 213eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 214eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n");CHKERRQ(ierr); 215eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 216eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr); 217eb1f6c34SBarry Smith } 218eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 219eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n");CHKERRQ(ierr); 220eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 22142f4f86dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr); 222eb1f6c34SBarry Smith } 2230f5bd95cSBarry Smith } else if (isstring) { 224317d6ea6SBarry Smith const char *type; 225454a90a3SBarry Smith ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 226b0a32e0cSBarry Smith ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr); 22719bcc07fSBarry Smith } 22842f4f86dSBarry Smith if (snes->pc && snes->usespc) { 2294a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2304a0c5b0cSMatthew G Knepley ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr); 2314a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2324a0c5b0cSMatthew G Knepley } 2332c155ee1SBarry Smith if (snes->usesksp) { 2342c155ee1SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 235b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 23694b7f48cSBarry Smith ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 237b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2382c155ee1SBarry Smith } 2399e764e56SPeter Brune ierr = PetscViewerASCIIPrintf(viewer, " line search variant: %s\n",((PetscObject)snes->linesearch)->type_name);CHKERRQ(ierr); 2403a40ed3dSBarry Smith PetscFunctionReturn(0); 2419b94acceSBarry Smith } 2429b94acceSBarry Smith 24376b2cf59SMatthew Knepley /* 24476b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 24576b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 24676b2cf59SMatthew Knepley */ 24776b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 248a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 2496849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 25076b2cf59SMatthew Knepley 251e74ef692SMatthew Knepley #undef __FUNCT__ 252e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker" 253ac226902SBarry Smith /*@C 25476b2cf59SMatthew Knepley SNESAddOptionsChecker - Adds an additional function to check for SNES options. 25576b2cf59SMatthew Knepley 25676b2cf59SMatthew Knepley Not Collective 25776b2cf59SMatthew Knepley 25876b2cf59SMatthew Knepley Input Parameter: 25976b2cf59SMatthew Knepley . snescheck - function that checks for options 26076b2cf59SMatthew Knepley 26176b2cf59SMatthew Knepley Level: developer 26276b2cf59SMatthew Knepley 26376b2cf59SMatthew Knepley .seealso: SNESSetFromOptions() 26476b2cf59SMatthew Knepley @*/ 2657087cfbeSBarry Smith PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 26676b2cf59SMatthew Knepley { 26776b2cf59SMatthew Knepley PetscFunctionBegin; 26876b2cf59SMatthew Knepley if (numberofsetfromoptions >= MAXSETFROMOPTIONS) { 269e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 27076b2cf59SMatthew Knepley } 27176b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 27276b2cf59SMatthew Knepley PetscFunctionReturn(0); 27376b2cf59SMatthew Knepley } 27476b2cf59SMatthew Knepley 2757087cfbeSBarry Smith extern PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 276aa3661deSLisandro Dalcin 277aa3661deSLisandro Dalcin #undef __FUNCT__ 278aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private" 279ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 280aa3661deSLisandro Dalcin { 281aa3661deSLisandro Dalcin Mat J; 282aa3661deSLisandro Dalcin KSP ksp; 283aa3661deSLisandro Dalcin PC pc; 284ace3abfcSBarry Smith PetscBool match; 285aa3661deSLisandro Dalcin PetscErrorCode ierr; 286aa3661deSLisandro Dalcin 287aa3661deSLisandro Dalcin PetscFunctionBegin; 2880700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 289aa3661deSLisandro Dalcin 29098613b67SLisandro Dalcin if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 29198613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 29298613b67SLisandro Dalcin ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr); 29398613b67SLisandro Dalcin } 29498613b67SLisandro Dalcin 295aa3661deSLisandro Dalcin if (version == 1) { 296aa3661deSLisandro Dalcin ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 29798613b67SLisandro Dalcin ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 2989c6ac3b3SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 299aa3661deSLisandro Dalcin } else if (version == 2) { 300e32f2f54SBarry Smith if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 30182a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 302aa3661deSLisandro Dalcin ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr); 303aa3661deSLisandro Dalcin #else 304e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)"); 305aa3661deSLisandro Dalcin #endif 306a8248277SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2"); 307aa3661deSLisandro Dalcin 308aa3661deSLisandro Dalcin ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr); 309d3462f78SMatthew Knepley if (hasOperator) { 310aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 311aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 312aa3661deSLisandro Dalcin ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 313aa3661deSLisandro Dalcin } else { 314aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 315aa3661deSLisandro Dalcin provided preconditioner matrix with the default matrix free version. */ 3166cab3a1bSJed Brown void *functx; 3176cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 3186cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr); 319aa3661deSLisandro Dalcin /* Force no preconditioner */ 320aa3661deSLisandro Dalcin ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 321aa3661deSLisandro Dalcin ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 322aa3661deSLisandro Dalcin ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr); 323aa3661deSLisandro Dalcin if (!match) { 324aa3661deSLisandro Dalcin ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 325aa3661deSLisandro Dalcin ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 326aa3661deSLisandro Dalcin } 327aa3661deSLisandro Dalcin } 3286bf464f9SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 329aa3661deSLisandro Dalcin PetscFunctionReturn(0); 330aa3661deSLisandro Dalcin } 331aa3661deSLisandro Dalcin 3324a2ae208SSatish Balay #undef __FUNCT__ 3336cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices" 3346cab3a1bSJed Brown /*@ 3356cab3a1bSJed Brown SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX() 3366cab3a1bSJed Brown 3376cab3a1bSJed Brown Collective 3386cab3a1bSJed Brown 3396cab3a1bSJed Brown Input Arguments: 3406cab3a1bSJed Brown . snes - snes to configure 3416cab3a1bSJed Brown 3426cab3a1bSJed Brown Level: developer 3436cab3a1bSJed Brown 3446cab3a1bSJed Brown .seealso: SNESSetUp() 3456cab3a1bSJed Brown @*/ 3466cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes) 3476cab3a1bSJed Brown { 3486cab3a1bSJed Brown PetscErrorCode ierr; 3496cab3a1bSJed Brown DM dm; 3506cab3a1bSJed Brown SNESDM sdm; 3516cab3a1bSJed Brown 3526cab3a1bSJed Brown PetscFunctionBegin; 3536cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3546cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 3556cab3a1bSJed Brown if (!sdm->computejacobian && snes->dm) { 3566cab3a1bSJed Brown Mat J,B; 3576cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 3586cab3a1bSJed Brown if (snes->mf_operator) { 3596cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 3606cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 3616cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 3626cab3a1bSJed Brown } else { 3636cab3a1bSJed Brown J = B; 3646cab3a1bSJed Brown ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr); 3656cab3a1bSJed Brown } 3666cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr); 3676cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 3686cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 3696cab3a1bSJed Brown } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) { 3706cab3a1bSJed Brown Mat J; 3716cab3a1bSJed Brown void *functx; 3726cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 3736cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 3746cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 3756cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 3766cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr); 3776cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 3786cab3a1bSJed Brown } else if (snes->dm && snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 3796cab3a1bSJed Brown Mat J,B; 3806cab3a1bSJed Brown void *functx; 3816cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 3826cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 3836cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 3846cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 3856cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 3866cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,functx);CHKERRQ(ierr); 3876cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 3886cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 3896cab3a1bSJed Brown } else if (snes->dm && !snes->jacobian_pre) { 3906cab3a1bSJed Brown Mat J,B; 3916cab3a1bSJed Brown J = snes->jacobian; 3926cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 3936cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 3946cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 3956cab3a1bSJed Brown } 3966cab3a1bSJed Brown PetscFunctionReturn(0); 3976cab3a1bSJed Brown } 3986cab3a1bSJed Brown 3996cab3a1bSJed Brown #undef __FUNCT__ 4004a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions" 4019b94acceSBarry Smith /*@ 40294b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 4039b94acceSBarry Smith 404c7afd0dbSLois Curfman McInnes Collective on SNES 405c7afd0dbSLois Curfman McInnes 4069b94acceSBarry Smith Input Parameter: 4079b94acceSBarry Smith . snes - the SNES context 4089b94acceSBarry Smith 40936851e7fSLois Curfman McInnes Options Database Keys: 410ea630c6eSPeter Brune + -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas 41182738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 41282738288SBarry Smith of the change in the solution between steps 41370441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 414b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 415b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 416b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 4174839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 418ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 419a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 420e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 421b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 4222492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 42382738288SBarry Smith solver; hence iterations will continue until max_it 4241fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 42582738288SBarry Smith of convergence test 426e8105e01SRichard Katz . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 427e8105e01SRichard Katz filename given prints to stdout 428a6570f20SBarry Smith . -snes_monitor_solution - plots solution at each iteration 429a6570f20SBarry Smith . -snes_monitor_residual - plots residual (not its norm) at each iteration 430a6570f20SBarry Smith . -snes_monitor_solution_update - plots update to solution at each iteration 431a6570f20SBarry Smith . -snes_monitor_draw - plots residual norm at each iteration 432e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 4335968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 434fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 43582738288SBarry Smith 43682738288SBarry Smith Options Database for Eisenstat-Walker method: 437fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 4384b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 43936851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 44036851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 44136851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 44236851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 44336851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 44436851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 44582738288SBarry Smith 44611ca99fdSLois Curfman McInnes Notes: 44711ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 4480598bfebSBarry Smith the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>. 44983e2fdc7SBarry Smith 45036851e7fSLois Curfman McInnes Level: beginner 45136851e7fSLois Curfman McInnes 4529b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 4539b94acceSBarry Smith 45469ed319cSSatish Balay .seealso: SNESSetOptionsPrefix() 4559b94acceSBarry Smith @*/ 4567087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 4579b94acceSBarry Smith { 458ea630c6eSPeter Brune PetscBool flg,set,mf,mf_operator,pcset; 459efd51863SBarry Smith PetscInt i,indx,lag,mf_version,grids; 460aa3661deSLisandro Dalcin MatStructure matflag; 46185385478SLisandro Dalcin const char *deft = SNESLS; 46285385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 46385385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 464e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 46551e86f29SPeter Brune const char *optionsprefix; 466649052a6SBarry Smith PetscViewer monviewer; 46785385478SLisandro Dalcin PetscErrorCode ierr; 4689b94acceSBarry Smith 4693a40ed3dSBarry Smith PetscFunctionBegin; 4700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 471ca161407SBarry Smith 472186905e3SBarry Smith if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 4733194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 4747adad957SLisandro Dalcin if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; } 475b0a32e0cSBarry Smith ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 476d64ed03dSBarry Smith if (flg) { 477186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 4787adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 479186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 480d64ed03dSBarry Smith } 48190d69ab7SBarry Smith /* not used here, but called so will go into help messaage */ 482909c8a9fSBarry Smith ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 48393c39befSBarry Smith 48457034d6fSHong Zhang ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->xtol,&snes->xtol,0);CHKERRQ(ierr); 48557034d6fSHong Zhang ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 486186905e3SBarry Smith 48757034d6fSHong Zhang ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 488b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 489b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 49050ffb88aSMatthew Knepley ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 491ddf469c8SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr); 492acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr); 49385385478SLisandro Dalcin 494a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 495a8054027SBarry Smith if (flg) { 496a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 497a8054027SBarry Smith } 498e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 499e35cf81dSBarry Smith if (flg) { 500e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 501e35cf81dSBarry Smith } 502efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 503efd51863SBarry Smith if (flg) { 504efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 505efd51863SBarry Smith } 506a8054027SBarry Smith 50785385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 50885385478SLisandro Dalcin if (flg) { 50985385478SLisandro Dalcin switch (indx) { 5107f7931b9SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 5117f7931b9SBarry Smith case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 51285385478SLisandro Dalcin } 51385385478SLisandro Dalcin } 51485385478SLisandro Dalcin 515acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr); 516186905e3SBarry Smith 51785385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 51885385478SLisandro Dalcin 519acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 520186905e3SBarry Smith 521fa9f3622SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 522fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 523fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 524fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 525fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 526fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 527fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 528186905e3SBarry Smith 52990d69ab7SBarry Smith flg = PETSC_FALSE; 530acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 531a6570f20SBarry Smith if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 532eabae89aSBarry Smith 533a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 534e8105e01SRichard Katz if (flg) { 535649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 536649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 537e8105e01SRichard Katz } 538eabae89aSBarry Smith 539b271bb04SBarry Smith ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 540b271bb04SBarry Smith if (flg) { 541b271bb04SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 542b271bb04SBarry Smith } 543b271bb04SBarry Smith 544a6570f20SBarry Smith ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 545eabae89aSBarry Smith if (flg) { 546649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 547f1bef1bcSMatthew Knepley ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 548e8105e01SRichard Katz } 549eabae89aSBarry Smith 550a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 551eabae89aSBarry Smith if (flg) { 552649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 553649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 554eabae89aSBarry Smith } 555eabae89aSBarry Smith 5565180491cSLisandro Dalcin ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 5575180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 5585180491cSLisandro Dalcin 55990d69ab7SBarry Smith flg = PETSC_FALSE; 560acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 561a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 56290d69ab7SBarry Smith flg = PETSC_FALSE; 563acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 564a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 56590d69ab7SBarry Smith flg = PETSC_FALSE; 566acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 567a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 56890d69ab7SBarry Smith flg = PETSC_FALSE; 569acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 570a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 57190d69ab7SBarry Smith flg = PETSC_FALSE; 572acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 573b271bb04SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 574e24b481bSBarry Smith 57590d69ab7SBarry Smith flg = PETSC_FALSE; 576acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 5774b27c08aSLois Curfman McInnes if (flg) { 5786cab3a1bSJed Brown void *functx; 5796cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 5806cab3a1bSJed Brown ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr); 581ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 5829b94acceSBarry Smith } 583639f9d9dSBarry Smith 584aa3661deSLisandro Dalcin mf = mf_operator = PETSC_FALSE; 585aa3661deSLisandro Dalcin flg = PETSC_FALSE; 586acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr); 587a8248277SBarry Smith if (flg && mf_operator) { 588a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 589a8248277SBarry Smith mf = PETSC_TRUE; 590a8248277SBarry Smith } 591aa3661deSLisandro Dalcin flg = PETSC_FALSE; 592acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr); 593aa3661deSLisandro Dalcin if (!flg && mf_operator) mf = PETSC_TRUE; 594aa3661deSLisandro Dalcin mf_version = 1; 595aa3661deSLisandro Dalcin ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr); 596aa3661deSLisandro Dalcin 597d28543b3SPeter Brune 59889b92e6fSPeter Brune /* GS Options */ 59989b92e6fSPeter Brune ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr); 60089b92e6fSPeter Brune 601ea630c6eSPeter Brune /* line search options */ 602ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_alpha","Constant function norm must decrease by","None",snes->ls_alpha,&snes->ls_alpha,0);CHKERRQ(ierr); 603ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_maxstep","Step must be less than","None",snes->maxstep,&snes->maxstep,0);CHKERRQ(ierr); 604ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_steptol","Minimum lambda allowed","None",snes->steptol,&snes->steptol,0);CHKERRQ(ierr); 605ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_damping","Damping parameter","SNES",snes->damping,&snes->damping,&flg);CHKERRQ(ierr); 606af60355fSPeter Brune ierr = PetscOptionsInt("-snes_ls_it" ,"Line search iterations","SNES",snes->ls_its,&snes->ls_its,&flg);CHKERRQ(ierr); 607ea630c6eSPeter Brune ierr = PetscOptionsBool("-snes_ls_monitor","Print progress of line searches","SNESLineSearchSetMonitor",snes->ls_monitor ? PETSC_TRUE : PETSC_FALSE,&flg,&set);CHKERRQ(ierr); 608ea630c6eSPeter Brune if (set) {ierr = SNESLineSearchSetMonitor(snes,flg);CHKERRQ(ierr);} 60915f5eeeaSPeter Brune ierr = PetscOptionsEnum("-snes_ls","Line search used","SNESLineSearchSet",SNESLineSearchTypes,(PetscEnum)snes->ls_type,(PetscEnum*)&indx,&flg);CHKERRQ(ierr); 61015f5eeeaSPeter Brune if (flg) { 611ea630c6eSPeter Brune ierr = SNESLineSearchSetType(snes,(SNESLineSearchType)indx);CHKERRQ(ierr); 61215f5eeeaSPeter Brune } 6138e3fc8c0SJed Brown flg = snes->ops->precheckstep == SNESLineSearchPreCheckPicard ? PETSC_TRUE : PETSC_FALSE; 6148e3fc8c0SJed Brown ierr = PetscOptionsBool("-snes_ls_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);CHKERRQ(ierr); 6158e3fc8c0SJed Brown if (set) { 6168e3fc8c0SJed Brown if (flg) { 6178e3fc8c0SJed Brown snes->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */ 6188e3fc8c0SJed Brown ierr = PetscOptionsReal("-snes_ls_precheck_picard_angle","Maximum angle at which to activate the correction","none",snes->precheck_picard_angle,&snes->precheck_picard_angle,PETSC_NULL);CHKERRQ(ierr); 6198e3fc8c0SJed Brown ierr = SNESLineSearchSetPreCheck(snes,SNESLineSearchPreCheckPicard,&snes->precheck_picard_angle);CHKERRQ(ierr); 6208e3fc8c0SJed Brown } else { 6218e3fc8c0SJed Brown ierr = SNESLineSearchSetPreCheck(snes,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 6228e3fc8c0SJed Brown } 6238e3fc8c0SJed Brown } 6248e3fc8c0SJed Brown 62576b2cf59SMatthew Knepley for(i = 0; i < numberofsetfromoptions; i++) { 62676b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 62776b2cf59SMatthew Knepley } 62876b2cf59SMatthew Knepley 629e7788613SBarry Smith if (snes->ops->setfromoptions) { 630e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 631639f9d9dSBarry Smith } 6325d973c19SBarry Smith 6335d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 6345d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 635b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 6364bbc92c1SBarry Smith 637aa3661deSLisandro Dalcin if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 6381cee3971SBarry Smith 6391cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 640aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 641aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 64285385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 64393993e2dSLois Curfman McInnes 6449e764e56SPeter Brune if (!snes->linesearch) { 6459e764e56SPeter Brune ierr = SNESGetPetscLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 6469e764e56SPeter Brune } 6479e764e56SPeter Brune ierr = PetscLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr); 6489e764e56SPeter Brune 64951e86f29SPeter Brune /* if someone has set the SNES PC type, create it. */ 65051e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 65151e86f29SPeter Brune ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 65251e86f29SPeter Brune if (pcset && (!snes->pc)) { 65351e86f29SPeter Brune ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr); 65451e86f29SPeter Brune } 6554a0c5b0cSMatthew G Knepley if (snes->pc) { 656fde0ff24SPeter Brune ierr = SNESSetOptionsPrefix(snes->pc, optionsprefix);CHKERRQ(ierr); 657fde0ff24SPeter Brune ierr = SNESAppendOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr); 6584a0c5b0cSMatthew G Knepley ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 6594a0c5b0cSMatthew G Knepley ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 6604a0c5b0cSMatthew G Knepley } 6613a40ed3dSBarry Smith PetscFunctionReturn(0); 6629b94acceSBarry Smith } 6639b94acceSBarry Smith 664d25893d9SBarry Smith #undef __FUNCT__ 665d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 666d25893d9SBarry Smith /*@ 667d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 668d25893d9SBarry Smith the nonlinear solvers. 669d25893d9SBarry Smith 670d25893d9SBarry Smith Logically Collective on SNES 671d25893d9SBarry Smith 672d25893d9SBarry Smith Input Parameters: 673d25893d9SBarry Smith + snes - the SNES context 674d25893d9SBarry Smith . compute - function to compute the context 675d25893d9SBarry Smith - destroy - function to destroy the context 676d25893d9SBarry Smith 677d25893d9SBarry Smith Level: intermediate 678d25893d9SBarry Smith 679d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 680d25893d9SBarry Smith 681d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 682d25893d9SBarry Smith @*/ 683d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 684d25893d9SBarry Smith { 685d25893d9SBarry Smith PetscFunctionBegin; 686d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 687d25893d9SBarry Smith snes->ops->usercompute = compute; 688d25893d9SBarry Smith snes->ops->userdestroy = destroy; 689d25893d9SBarry Smith PetscFunctionReturn(0); 690d25893d9SBarry Smith } 691a847f771SSatish Balay 6924a2ae208SSatish Balay #undef __FUNCT__ 6934a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 694b07ff414SBarry Smith /*@ 6959b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 6969b94acceSBarry Smith the nonlinear solvers. 6979b94acceSBarry Smith 6983f9fe445SBarry Smith Logically Collective on SNES 699fee21e36SBarry Smith 700c7afd0dbSLois Curfman McInnes Input Parameters: 701c7afd0dbSLois Curfman McInnes + snes - the SNES context 702c7afd0dbSLois Curfman McInnes - usrP - optional user context 703c7afd0dbSLois Curfman McInnes 70436851e7fSLois Curfman McInnes Level: intermediate 70536851e7fSLois Curfman McInnes 7069b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 7079b94acceSBarry Smith 708d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext() 7099b94acceSBarry Smith @*/ 7107087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 7119b94acceSBarry Smith { 7121b2093e4SBarry Smith PetscErrorCode ierr; 713b07ff414SBarry Smith KSP ksp; 7141b2093e4SBarry Smith 7153a40ed3dSBarry Smith PetscFunctionBegin; 7160700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 717b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 718b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 7199b94acceSBarry Smith snes->user = usrP; 7203a40ed3dSBarry Smith PetscFunctionReturn(0); 7219b94acceSBarry Smith } 72274679c65SBarry Smith 7234a2ae208SSatish Balay #undef __FUNCT__ 7244a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 725b07ff414SBarry Smith /*@ 7269b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 7279b94acceSBarry Smith nonlinear solvers. 7289b94acceSBarry Smith 729c7afd0dbSLois Curfman McInnes Not Collective 730c7afd0dbSLois Curfman McInnes 7319b94acceSBarry Smith Input Parameter: 7329b94acceSBarry Smith . snes - SNES context 7339b94acceSBarry Smith 7349b94acceSBarry Smith Output Parameter: 7359b94acceSBarry Smith . usrP - user context 7369b94acceSBarry Smith 73736851e7fSLois Curfman McInnes Level: intermediate 73836851e7fSLois Curfman McInnes 7399b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 7409b94acceSBarry Smith 7419b94acceSBarry Smith .seealso: SNESSetApplicationContext() 7429b94acceSBarry Smith @*/ 743e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 7449b94acceSBarry Smith { 7453a40ed3dSBarry Smith PetscFunctionBegin; 7460700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 747e71120c6SJed Brown *(void**)usrP = snes->user; 7483a40ed3dSBarry Smith PetscFunctionReturn(0); 7499b94acceSBarry Smith } 75074679c65SBarry Smith 7514a2ae208SSatish Balay #undef __FUNCT__ 7524a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 7539b94acceSBarry Smith /*@ 754c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 755c8228a4eSBarry Smith at this time. 7569b94acceSBarry Smith 757c7afd0dbSLois Curfman McInnes Not Collective 758c7afd0dbSLois Curfman McInnes 7599b94acceSBarry Smith Input Parameter: 7609b94acceSBarry Smith . snes - SNES context 7619b94acceSBarry Smith 7629b94acceSBarry Smith Output Parameter: 7639b94acceSBarry Smith . iter - iteration number 7649b94acceSBarry Smith 765c8228a4eSBarry Smith Notes: 766c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 767c8228a4eSBarry Smith 768c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 76908405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 77008405cd6SLois Curfman McInnes .vb 77108405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 77208405cd6SLois Curfman McInnes if (!(it % 2)) { 77308405cd6SLois Curfman McInnes [compute Jacobian here] 77408405cd6SLois Curfman McInnes } 77508405cd6SLois Curfman McInnes .ve 776c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 77708405cd6SLois Curfman McInnes recomputed every second SNES iteration. 778c8228a4eSBarry Smith 77936851e7fSLois Curfman McInnes Level: intermediate 78036851e7fSLois Curfman McInnes 7812b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 7822b668275SBarry Smith 783b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 7849b94acceSBarry Smith @*/ 7857087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 7869b94acceSBarry Smith { 7873a40ed3dSBarry Smith PetscFunctionBegin; 7880700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7894482741eSBarry Smith PetscValidIntPointer(iter,2); 7909b94acceSBarry Smith *iter = snes->iter; 7913a40ed3dSBarry Smith PetscFunctionReturn(0); 7929b94acceSBarry Smith } 79374679c65SBarry Smith 7944a2ae208SSatish Balay #undef __FUNCT__ 795360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber" 796360c497dSPeter Brune /*@ 797360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 798360c497dSPeter Brune 799360c497dSPeter Brune Not Collective 800360c497dSPeter Brune 801360c497dSPeter Brune Input Parameter: 802360c497dSPeter Brune . snes - SNES context 803360c497dSPeter Brune . iter - iteration number 804360c497dSPeter Brune 805360c497dSPeter Brune Level: developer 806360c497dSPeter Brune 807360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number, 808360c497dSPeter Brune 809360c497dSPeter Brune .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 810360c497dSPeter Brune @*/ 811360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 812360c497dSPeter Brune { 813360c497dSPeter Brune PetscErrorCode ierr; 814360c497dSPeter Brune 815360c497dSPeter Brune PetscFunctionBegin; 816360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 817360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 818360c497dSPeter Brune snes->iter = iter; 819360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 820360c497dSPeter Brune PetscFunctionReturn(0); 821360c497dSPeter Brune } 822360c497dSPeter Brune 823360c497dSPeter Brune #undef __FUNCT__ 8244a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 8259b94acceSBarry Smith /*@ 8269b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 8279b94acceSBarry Smith with SNESSSetFunction(). 8289b94acceSBarry Smith 829c7afd0dbSLois Curfman McInnes Collective on SNES 830c7afd0dbSLois Curfman McInnes 8319b94acceSBarry Smith Input Parameter: 8329b94acceSBarry Smith . snes - SNES context 8339b94acceSBarry Smith 8349b94acceSBarry Smith Output Parameter: 8359b94acceSBarry Smith . fnorm - 2-norm of function 8369b94acceSBarry Smith 83736851e7fSLois Curfman McInnes Level: intermediate 83836851e7fSLois Curfman McInnes 8399b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 840a86d99e1SLois Curfman McInnes 841b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 8429b94acceSBarry Smith @*/ 8437087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 8449b94acceSBarry Smith { 8453a40ed3dSBarry Smith PetscFunctionBegin; 8460700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8474482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 8489b94acceSBarry Smith *fnorm = snes->norm; 8493a40ed3dSBarry Smith PetscFunctionReturn(0); 8509b94acceSBarry Smith } 85174679c65SBarry Smith 852360c497dSPeter Brune 853360c497dSPeter Brune #undef __FUNCT__ 854360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm" 855360c497dSPeter Brune /*@ 856360c497dSPeter Brune SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm(). 857360c497dSPeter Brune 858360c497dSPeter Brune Collective on SNES 859360c497dSPeter Brune 860360c497dSPeter Brune Input Parameter: 861360c497dSPeter Brune . snes - SNES context 862360c497dSPeter Brune . fnorm - 2-norm of function 863360c497dSPeter Brune 864360c497dSPeter Brune Level: developer 865360c497dSPeter Brune 866360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm 867360c497dSPeter Brune 868360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm(). 869360c497dSPeter Brune @*/ 870360c497dSPeter Brune PetscErrorCode SNESSetFunctionNorm(SNES snes,PetscReal fnorm) 871360c497dSPeter Brune { 872360c497dSPeter Brune 873360c497dSPeter Brune PetscErrorCode ierr; 874360c497dSPeter Brune 875360c497dSPeter Brune PetscFunctionBegin; 876360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 877360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 878360c497dSPeter Brune snes->norm = fnorm; 879360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 880360c497dSPeter Brune PetscFunctionReturn(0); 881360c497dSPeter Brune } 882360c497dSPeter Brune 8834a2ae208SSatish Balay #undef __FUNCT__ 884b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 8859b94acceSBarry Smith /*@ 886b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 8879b94acceSBarry Smith attempted by the nonlinear solver. 8889b94acceSBarry Smith 889c7afd0dbSLois Curfman McInnes Not Collective 890c7afd0dbSLois Curfman McInnes 8919b94acceSBarry Smith Input Parameter: 8929b94acceSBarry Smith . snes - SNES context 8939b94acceSBarry Smith 8949b94acceSBarry Smith Output Parameter: 8959b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 8969b94acceSBarry Smith 897c96a6f78SLois Curfman McInnes Notes: 898c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 899c96a6f78SLois Curfman McInnes 90036851e7fSLois Curfman McInnes Level: intermediate 90136851e7fSLois Curfman McInnes 9029b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 90358ebbce7SBarry Smith 904e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 90558ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 9069b94acceSBarry Smith @*/ 9077087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 9089b94acceSBarry Smith { 9093a40ed3dSBarry Smith PetscFunctionBegin; 9100700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9114482741eSBarry Smith PetscValidIntPointer(nfails,2); 91250ffb88aSMatthew Knepley *nfails = snes->numFailures; 91350ffb88aSMatthew Knepley PetscFunctionReturn(0); 91450ffb88aSMatthew Knepley } 91550ffb88aSMatthew Knepley 91650ffb88aSMatthew Knepley #undef __FUNCT__ 917b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 91850ffb88aSMatthew Knepley /*@ 919b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 92050ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 92150ffb88aSMatthew Knepley 92250ffb88aSMatthew Knepley Not Collective 92350ffb88aSMatthew Knepley 92450ffb88aSMatthew Knepley Input Parameters: 92550ffb88aSMatthew Knepley + snes - SNES context 92650ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 92750ffb88aSMatthew Knepley 92850ffb88aSMatthew Knepley Level: intermediate 92950ffb88aSMatthew Knepley 93050ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 93158ebbce7SBarry Smith 932e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 93358ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 93450ffb88aSMatthew Knepley @*/ 9357087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 93650ffb88aSMatthew Knepley { 93750ffb88aSMatthew Knepley PetscFunctionBegin; 9380700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 93950ffb88aSMatthew Knepley snes->maxFailures = maxFails; 94050ffb88aSMatthew Knepley PetscFunctionReturn(0); 94150ffb88aSMatthew Knepley } 94250ffb88aSMatthew Knepley 94350ffb88aSMatthew Knepley #undef __FUNCT__ 944b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 94550ffb88aSMatthew Knepley /*@ 946b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 94750ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 94850ffb88aSMatthew Knepley 94950ffb88aSMatthew Knepley Not Collective 95050ffb88aSMatthew Knepley 95150ffb88aSMatthew Knepley Input Parameter: 95250ffb88aSMatthew Knepley . snes - SNES context 95350ffb88aSMatthew Knepley 95450ffb88aSMatthew Knepley Output Parameter: 95550ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 95650ffb88aSMatthew Knepley 95750ffb88aSMatthew Knepley Level: intermediate 95850ffb88aSMatthew Knepley 95950ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 96058ebbce7SBarry Smith 961e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 96258ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 96358ebbce7SBarry Smith 96450ffb88aSMatthew Knepley @*/ 9657087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 96650ffb88aSMatthew Knepley { 96750ffb88aSMatthew Knepley PetscFunctionBegin; 9680700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9694482741eSBarry Smith PetscValidIntPointer(maxFails,2); 97050ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 9713a40ed3dSBarry Smith PetscFunctionReturn(0); 9729b94acceSBarry Smith } 973a847f771SSatish Balay 9744a2ae208SSatish Balay #undef __FUNCT__ 9752541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 9762541af92SBarry Smith /*@ 9772541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 9782541af92SBarry Smith done by SNES. 9792541af92SBarry Smith 9802541af92SBarry Smith Not Collective 9812541af92SBarry Smith 9822541af92SBarry Smith Input Parameter: 9832541af92SBarry Smith . snes - SNES context 9842541af92SBarry Smith 9852541af92SBarry Smith Output Parameter: 9862541af92SBarry Smith . nfuncs - number of evaluations 9872541af92SBarry Smith 9882541af92SBarry Smith Level: intermediate 9892541af92SBarry Smith 9902541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 99158ebbce7SBarry Smith 992e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 9932541af92SBarry Smith @*/ 9947087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 9952541af92SBarry Smith { 9962541af92SBarry Smith PetscFunctionBegin; 9970700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9982541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 9992541af92SBarry Smith *nfuncs = snes->nfuncs; 10002541af92SBarry Smith PetscFunctionReturn(0); 10012541af92SBarry Smith } 10022541af92SBarry Smith 10032541af92SBarry Smith #undef __FUNCT__ 10043d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 10053d4c4710SBarry Smith /*@ 10063d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 10073d4c4710SBarry Smith linear solvers. 10083d4c4710SBarry Smith 10093d4c4710SBarry Smith Not Collective 10103d4c4710SBarry Smith 10113d4c4710SBarry Smith Input Parameter: 10123d4c4710SBarry Smith . snes - SNES context 10133d4c4710SBarry Smith 10143d4c4710SBarry Smith Output Parameter: 10153d4c4710SBarry Smith . nfails - number of failed solves 10163d4c4710SBarry Smith 10173d4c4710SBarry Smith Notes: 10183d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 10193d4c4710SBarry Smith 10203d4c4710SBarry Smith Level: intermediate 10213d4c4710SBarry Smith 10223d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 102358ebbce7SBarry Smith 1024e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 10253d4c4710SBarry Smith @*/ 10267087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 10273d4c4710SBarry Smith { 10283d4c4710SBarry Smith PetscFunctionBegin; 10290700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10303d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 10313d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 10323d4c4710SBarry Smith PetscFunctionReturn(0); 10333d4c4710SBarry Smith } 10343d4c4710SBarry Smith 10353d4c4710SBarry Smith #undef __FUNCT__ 10363d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 10373d4c4710SBarry Smith /*@ 10383d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 10393d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 10403d4c4710SBarry Smith 10413f9fe445SBarry Smith Logically Collective on SNES 10423d4c4710SBarry Smith 10433d4c4710SBarry Smith Input Parameters: 10443d4c4710SBarry Smith + snes - SNES context 10453d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 10463d4c4710SBarry Smith 10473d4c4710SBarry Smith Level: intermediate 10483d4c4710SBarry Smith 1049a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 10503d4c4710SBarry Smith 10513d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 10523d4c4710SBarry Smith 105358ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 10543d4c4710SBarry Smith @*/ 10557087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 10563d4c4710SBarry Smith { 10573d4c4710SBarry Smith PetscFunctionBegin; 10580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1059c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 10603d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 10613d4c4710SBarry Smith PetscFunctionReturn(0); 10623d4c4710SBarry Smith } 10633d4c4710SBarry Smith 10643d4c4710SBarry Smith #undef __FUNCT__ 10653d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 10663d4c4710SBarry Smith /*@ 10673d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 10683d4c4710SBarry Smith are allowed before SNES terminates 10693d4c4710SBarry Smith 10703d4c4710SBarry Smith Not Collective 10713d4c4710SBarry Smith 10723d4c4710SBarry Smith Input Parameter: 10733d4c4710SBarry Smith . snes - SNES context 10743d4c4710SBarry Smith 10753d4c4710SBarry Smith Output Parameter: 10763d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 10773d4c4710SBarry Smith 10783d4c4710SBarry Smith Level: intermediate 10793d4c4710SBarry Smith 10803d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 10813d4c4710SBarry Smith 10823d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 10833d4c4710SBarry Smith 1084e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 10853d4c4710SBarry Smith @*/ 10867087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 10873d4c4710SBarry Smith { 10883d4c4710SBarry Smith PetscFunctionBegin; 10890700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10903d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 10913d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 10923d4c4710SBarry Smith PetscFunctionReturn(0); 10933d4c4710SBarry Smith } 10943d4c4710SBarry Smith 10953d4c4710SBarry Smith #undef __FUNCT__ 1096b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 1097c96a6f78SLois Curfman McInnes /*@ 1098b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1099c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1100c96a6f78SLois Curfman McInnes 1101c7afd0dbSLois Curfman McInnes Not Collective 1102c7afd0dbSLois Curfman McInnes 1103c96a6f78SLois Curfman McInnes Input Parameter: 1104c96a6f78SLois Curfman McInnes . snes - SNES context 1105c96a6f78SLois Curfman McInnes 1106c96a6f78SLois Curfman McInnes Output Parameter: 1107c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1108c96a6f78SLois Curfman McInnes 1109c96a6f78SLois Curfman McInnes Notes: 1110c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1111c96a6f78SLois Curfman McInnes 111236851e7fSLois Curfman McInnes Level: intermediate 111336851e7fSLois Curfman McInnes 1114c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 11152b668275SBarry Smith 11168c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 1117c96a6f78SLois Curfman McInnes @*/ 11187087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 1119c96a6f78SLois Curfman McInnes { 11203a40ed3dSBarry Smith PetscFunctionBegin; 11210700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11224482741eSBarry Smith PetscValidIntPointer(lits,2); 1123c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 11243a40ed3dSBarry Smith PetscFunctionReturn(0); 1125c96a6f78SLois Curfman McInnes } 1126c96a6f78SLois Curfman McInnes 11274a2ae208SSatish Balay #undef __FUNCT__ 112894b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 112952baeb72SSatish Balay /*@ 113094b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 11319b94acceSBarry Smith 113294b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 1133c7afd0dbSLois Curfman McInnes 11349b94acceSBarry Smith Input Parameter: 11359b94acceSBarry Smith . snes - the SNES context 11369b94acceSBarry Smith 11379b94acceSBarry Smith Output Parameter: 113894b7f48cSBarry Smith . ksp - the KSP context 11399b94acceSBarry Smith 11409b94acceSBarry Smith Notes: 114194b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 11429b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 11432999313aSBarry Smith PC contexts as well. 11449b94acceSBarry Smith 114536851e7fSLois Curfman McInnes Level: beginner 114636851e7fSLois Curfman McInnes 114794b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 11489b94acceSBarry Smith 11492999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 11509b94acceSBarry Smith @*/ 11517087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 11529b94acceSBarry Smith { 11531cee3971SBarry Smith PetscErrorCode ierr; 11541cee3971SBarry Smith 11553a40ed3dSBarry Smith PetscFunctionBegin; 11560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11574482741eSBarry Smith PetscValidPointer(ksp,2); 11581cee3971SBarry Smith 11591cee3971SBarry Smith if (!snes->ksp) { 11601cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 11611cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 11621cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 11631cee3971SBarry Smith } 116494b7f48cSBarry Smith *ksp = snes->ksp; 11653a40ed3dSBarry Smith PetscFunctionReturn(0); 11669b94acceSBarry Smith } 116782bf6240SBarry Smith 11684a2ae208SSatish Balay #undef __FUNCT__ 11692999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 11702999313aSBarry Smith /*@ 11712999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 11722999313aSBarry Smith 11732999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 11742999313aSBarry Smith 11752999313aSBarry Smith Input Parameters: 11762999313aSBarry Smith + snes - the SNES context 11772999313aSBarry Smith - ksp - the KSP context 11782999313aSBarry Smith 11792999313aSBarry Smith Notes: 11802999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 11812999313aSBarry Smith so this routine is rarely needed. 11822999313aSBarry Smith 11832999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 11842999313aSBarry Smith decreased by one. 11852999313aSBarry Smith 11862999313aSBarry Smith Level: developer 11872999313aSBarry Smith 11882999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 11892999313aSBarry Smith 11902999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 11912999313aSBarry Smith @*/ 11927087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 11932999313aSBarry Smith { 11942999313aSBarry Smith PetscErrorCode ierr; 11952999313aSBarry Smith 11962999313aSBarry Smith PetscFunctionBegin; 11970700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11980700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 11992999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 12007dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1201906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 12022999313aSBarry Smith snes->ksp = ksp; 12032999313aSBarry Smith PetscFunctionReturn(0); 12042999313aSBarry Smith } 12052999313aSBarry Smith 12067adad957SLisandro Dalcin #if 0 12072999313aSBarry Smith #undef __FUNCT__ 12084a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 12096849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1210e24b481bSBarry Smith { 1211e24b481bSBarry Smith PetscFunctionBegin; 1212e24b481bSBarry Smith PetscFunctionReturn(0); 1213e24b481bSBarry Smith } 12147adad957SLisandro Dalcin #endif 1215e24b481bSBarry Smith 12169b94acceSBarry Smith /* -----------------------------------------------------------*/ 12174a2ae208SSatish Balay #undef __FUNCT__ 12184a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 121952baeb72SSatish Balay /*@ 12209b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 12219b94acceSBarry Smith 1222c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1223c7afd0dbSLois Curfman McInnes 1224c7afd0dbSLois Curfman McInnes Input Parameters: 1225906ed7ccSBarry Smith . comm - MPI communicator 12269b94acceSBarry Smith 12279b94acceSBarry Smith Output Parameter: 12289b94acceSBarry Smith . outsnes - the new SNES context 12299b94acceSBarry Smith 1230c7afd0dbSLois Curfman McInnes Options Database Keys: 1231c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1232c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1233c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1234c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1235c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1236c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1237c1f60f51SBarry Smith 123836851e7fSLois Curfman McInnes Level: beginner 123936851e7fSLois Curfman McInnes 12409b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 12419b94acceSBarry Smith 1242a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1243a8054027SBarry Smith 12449b94acceSBarry Smith @*/ 12457087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 12469b94acceSBarry Smith { 1247dfbe8321SBarry Smith PetscErrorCode ierr; 12489b94acceSBarry Smith SNES snes; 1249fa9f3622SBarry Smith SNESKSPEW *kctx; 125037fcc0dbSBarry Smith 12513a40ed3dSBarry Smith PetscFunctionBegin; 1252ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 12538ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 12548ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 12558ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 12568ba1e511SMatthew Knepley #endif 12578ba1e511SMatthew Knepley 12583194b578SJed Brown ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 12597adad957SLisandro Dalcin 126085385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 12612c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 12629b94acceSBarry Smith snes->max_its = 50; 12639750a799SBarry Smith snes->max_funcs = 10000; 12649b94acceSBarry Smith snes->norm = 0.0; 1265b4874afaSBarry Smith snes->rtol = 1.e-8; 1266b4874afaSBarry Smith snes->ttol = 0.0; 126770441072SBarry Smith snes->abstol = 1.e-50; 12689b94acceSBarry Smith snes->xtol = 1.e-8; 12694b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 12709b94acceSBarry Smith snes->nfuncs = 0; 127150ffb88aSMatthew Knepley snes->numFailures = 0; 127250ffb88aSMatthew Knepley snes->maxFailures = 1; 12737a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1274e35cf81dSBarry Smith snes->lagjacobian = 1; 1275a8054027SBarry Smith snes->lagpreconditioner = 1; 1276639f9d9dSBarry Smith snes->numbermonitors = 0; 12779b94acceSBarry Smith snes->data = 0; 12784dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1279186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 12806f24a144SLois Curfman McInnes snes->nwork = 0; 128158c9b817SLisandro Dalcin snes->work = 0; 128258c9b817SLisandro Dalcin snes->nvwork = 0; 128358c9b817SLisandro Dalcin snes->vwork = 0; 1284758f92a0SBarry Smith snes->conv_hist_len = 0; 1285758f92a0SBarry Smith snes->conv_hist_max = 0; 1286758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1287758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1288758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1289184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 129089b92e6fSPeter Brune snes->gssweeps = 1; 12919b94acceSBarry Smith 1292ea630c6eSPeter Brune /* initialize the line search options */ 12939e764e56SPeter Brune snes->linesearch = PETSC_NULL; 1294ea630c6eSPeter Brune snes->ls_type = SNES_LS_BASIC; 1295af60355fSPeter Brune snes->ls_its = 1; 1296ea630c6eSPeter Brune snes->damping = 1.0; 1297ea630c6eSPeter Brune snes->maxstep = 1e8; 1298ea630c6eSPeter Brune snes->steptol = 1e-12; 1299ea630c6eSPeter Brune snes->ls_alpha = 1e-4; 1300ea630c6eSPeter Brune snes->ls_monitor = PETSC_NULL; 1301ea630c6eSPeter Brune 1302ea630c6eSPeter Brune snes->ops->linesearch = PETSC_NULL; 1303ea630c6eSPeter Brune snes->precheck = PETSC_NULL; 1304ea630c6eSPeter Brune snes->ops->precheckstep = PETSC_NULL; 1305ea630c6eSPeter Brune snes->postcheck = PETSC_NULL; 1306ea630c6eSPeter Brune snes->ops->postcheckstep= PETSC_NULL; 1307ea630c6eSPeter Brune 13083d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 13093d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 13103d4c4710SBarry Smith 13119b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 131238f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 13139b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 13149b94acceSBarry Smith kctx->version = 2; 13159b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 13169b94acceSBarry Smith this was too large for some test cases */ 131775567043SBarry Smith kctx->rtol_last = 0.0; 13189b94acceSBarry Smith kctx->rtol_max = .9; 13199b94acceSBarry Smith kctx->gamma = 1.0; 132062d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 132171f87433Sdalcinl kctx->alpha2 = kctx->alpha; 13229b94acceSBarry Smith kctx->threshold = .1; 132375567043SBarry Smith kctx->lresid_last = 0.0; 132475567043SBarry Smith kctx->norm_last = 0.0; 13259b94acceSBarry Smith 13269b94acceSBarry Smith *outsnes = snes; 13273a40ed3dSBarry Smith PetscFunctionReturn(0); 13289b94acceSBarry Smith } 13299b94acceSBarry Smith 13304a2ae208SSatish Balay #undef __FUNCT__ 13314a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 13329b94acceSBarry Smith /*@C 13339b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 13349b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 13359b94acceSBarry Smith equations. 13369b94acceSBarry Smith 13373f9fe445SBarry Smith Logically Collective on SNES 1338fee21e36SBarry Smith 1339c7afd0dbSLois Curfman McInnes Input Parameters: 1340c7afd0dbSLois Curfman McInnes + snes - the SNES context 1341c7afd0dbSLois Curfman McInnes . r - vector to store function value 1342de044059SHong Zhang . func - function evaluation routine 1343c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1344c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 13459b94acceSBarry Smith 1346c7afd0dbSLois Curfman McInnes Calling sequence of func: 13478d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1348c7afd0dbSLois Curfman McInnes 1349*c586c404SJed Brown + snes - the SNES context 1350*c586c404SJed Brown . x - state at which to evaluate residual 1351*c586c404SJed Brown . f - vector to put residual 1352c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 13539b94acceSBarry Smith 13549b94acceSBarry Smith Notes: 13559b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 13569b94acceSBarry Smith $ f'(x) x = -f(x), 1357c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 13589b94acceSBarry Smith 135936851e7fSLois Curfman McInnes Level: beginner 136036851e7fSLois Curfman McInnes 13619b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 13629b94acceSBarry Smith 13638b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard() 13649b94acceSBarry Smith @*/ 13657087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 13669b94acceSBarry Smith { 136785385478SLisandro Dalcin PetscErrorCode ierr; 13686cab3a1bSJed Brown DM dm; 13696cab3a1bSJed Brown 13703a40ed3dSBarry Smith PetscFunctionBegin; 13710700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1372d2a683ecSLisandro Dalcin if (r) { 1373d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1374d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 137585385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 13766bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 137785385478SLisandro Dalcin snes->vec_func = r; 1378d2a683ecSLisandro Dalcin } 13796cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 13806cab3a1bSJed Brown ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr); 13813a40ed3dSBarry Smith PetscFunctionReturn(0); 13829b94acceSBarry Smith } 13839b94acceSBarry Smith 1384646217ecSPeter Brune 1385646217ecSPeter Brune #undef __FUNCT__ 1386646217ecSPeter Brune #define __FUNCT__ "SNESSetGS" 1387c79ef259SPeter Brune /*@C 1388c79ef259SPeter Brune SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for 1389c79ef259SPeter Brune use with composed nonlinear solvers. 1390c79ef259SPeter Brune 1391c79ef259SPeter Brune Input Parameters: 1392c79ef259SPeter Brune + snes - the SNES context 1393c79ef259SPeter Brune . gsfunc - function evaluation routine 1394c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 1395c79ef259SPeter Brune smoother evaluation routine (may be PETSC_NULL) 1396c79ef259SPeter Brune 1397c79ef259SPeter Brune Calling sequence of func: 1398c79ef259SPeter Brune $ func (SNES snes,Vec x,Vec b,void *ctx); 1399c79ef259SPeter Brune 1400c79ef259SPeter Brune + X - solution vector 1401c79ef259SPeter Brune . B - RHS vector 1402d28543b3SPeter Brune - ctx - optional user-defined Gauss-Seidel context 1403c79ef259SPeter Brune 1404c79ef259SPeter Brune Notes: 1405c79ef259SPeter Brune The GS routines are used by the composed nonlinear solver to generate 1406c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1407c79ef259SPeter Brune 1408d28543b3SPeter Brune Level: intermediate 1409c79ef259SPeter Brune 1410d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1411c79ef259SPeter Brune 1412c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS() 1413c79ef259SPeter Brune @*/ 14146cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx) 14156cab3a1bSJed Brown { 14166cab3a1bSJed Brown PetscErrorCode ierr; 14176cab3a1bSJed Brown DM dm; 14186cab3a1bSJed Brown 1419646217ecSPeter Brune PetscFunctionBegin; 14206cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14216cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 14226cab3a1bSJed Brown ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr); 1423646217ecSPeter Brune PetscFunctionReturn(0); 1424646217ecSPeter Brune } 1425646217ecSPeter Brune 1426d25893d9SBarry Smith #undef __FUNCT__ 142789b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps" 142889b92e6fSPeter Brune /*@ 142989b92e6fSPeter Brune SNESSetGSSweeps - Sets the number of sweeps of GS to use. 143089b92e6fSPeter Brune 143189b92e6fSPeter Brune Input Parameters: 143289b92e6fSPeter Brune + snes - the SNES context 143389b92e6fSPeter Brune - sweeps - the number of sweeps of GS to perform. 143489b92e6fSPeter Brune 143589b92e6fSPeter Brune Level: intermediate 143689b92e6fSPeter Brune 143789b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 143889b92e6fSPeter Brune 143989b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps() 144089b92e6fSPeter Brune @*/ 144189b92e6fSPeter Brune 144289b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) { 144389b92e6fSPeter Brune PetscFunctionBegin; 144489b92e6fSPeter Brune snes->gssweeps = sweeps; 144589b92e6fSPeter Brune PetscFunctionReturn(0); 144689b92e6fSPeter Brune } 144789b92e6fSPeter Brune 144889b92e6fSPeter Brune 144989b92e6fSPeter Brune #undef __FUNCT__ 145089b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps" 145189b92e6fSPeter Brune /*@ 145289b92e6fSPeter Brune SNESGetGSSweeps - Gets the number of sweeps GS will use. 145389b92e6fSPeter Brune 145489b92e6fSPeter Brune Input Parameters: 145589b92e6fSPeter Brune . snes - the SNES context 145689b92e6fSPeter Brune 145789b92e6fSPeter Brune Output Parameters: 145889b92e6fSPeter Brune . sweeps - the number of sweeps of GS to perform. 145989b92e6fSPeter Brune 146089b92e6fSPeter Brune Level: intermediate 146189b92e6fSPeter Brune 146289b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 146389b92e6fSPeter Brune 146489b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps() 146589b92e6fSPeter Brune @*/ 146689b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) { 146789b92e6fSPeter Brune PetscFunctionBegin; 146889b92e6fSPeter Brune *sweeps = snes->gssweeps; 146989b92e6fSPeter Brune PetscFunctionReturn(0); 147089b92e6fSPeter Brune } 147189b92e6fSPeter Brune 147289b92e6fSPeter Brune #undef __FUNCT__ 14738b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 14748b0a5094SBarry Smith PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 14758b0a5094SBarry Smith { 14768b0a5094SBarry Smith PetscErrorCode ierr; 14776cab3a1bSJed Brown void *functx,*jacctx; 14786cab3a1bSJed Brown 14798b0a5094SBarry Smith PetscFunctionBegin; 14806cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 14816cab3a1bSJed Brown ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr); 14828b0a5094SBarry Smith /* A(x)*x - b(x) */ 14836cab3a1bSJed Brown ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr); 14846cab3a1bSJed Brown ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr); 14858b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 14868b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 14878b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 14888b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 14898b0a5094SBarry Smith PetscFunctionReturn(0); 14908b0a5094SBarry Smith } 14918b0a5094SBarry Smith 14928b0a5094SBarry Smith #undef __FUNCT__ 14938b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 14948b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 14958b0a5094SBarry Smith { 14968b0a5094SBarry Smith PetscFunctionBegin; 14978b0a5094SBarry Smith *flag = snes->matstruct; 14988b0a5094SBarry Smith PetscFunctionReturn(0); 14998b0a5094SBarry Smith } 15008b0a5094SBarry Smith 15018b0a5094SBarry Smith #undef __FUNCT__ 15028b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 15038b0a5094SBarry Smith /*@C 15040d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 15058b0a5094SBarry Smith 15068b0a5094SBarry Smith Logically Collective on SNES 15078b0a5094SBarry Smith 15088b0a5094SBarry Smith Input Parameters: 15098b0a5094SBarry Smith + snes - the SNES context 15108b0a5094SBarry Smith . r - vector to store function value 15118b0a5094SBarry Smith . func - function evaluation routine 15128b0a5094SBarry 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) 15138b0a5094SBarry Smith . mat - matrix to store A 15148b0a5094SBarry Smith . mfunc - function to compute matrix value 15158b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 15168b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 15178b0a5094SBarry Smith 15188b0a5094SBarry Smith Calling sequence of func: 15198b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 15208b0a5094SBarry Smith 15218b0a5094SBarry Smith + f - function vector 15228b0a5094SBarry Smith - ctx - optional user-defined function context 15238b0a5094SBarry Smith 15248b0a5094SBarry Smith Calling sequence of mfunc: 15258b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 15268b0a5094SBarry Smith 15278b0a5094SBarry Smith + x - input vector 15288b0a5094SBarry 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(), 15298b0a5094SBarry Smith normally just pass mat in this location 15308b0a5094SBarry Smith . mat - form A(x) matrix 15318b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 15328b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 15338b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 15348b0a5094SBarry Smith 15358b0a5094SBarry Smith Notes: 15368b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 15378b0a5094SBarry Smith 15388b0a5094SBarry 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} 15398b0a5094SBarry 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. 15408b0a5094SBarry Smith 15418b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 15428b0a5094SBarry Smith 15430d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 15440d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 15458b0a5094SBarry Smith 15468b0a5094SBarry 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 15478b0a5094SBarry 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 15488b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 15498b0a5094SBarry Smith 15508b0a5094SBarry Smith Level: beginner 15518b0a5094SBarry Smith 15528b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 15538b0a5094SBarry Smith 15540d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard() 15558b0a5094SBarry Smith @*/ 15568b0a5094SBarry 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) 15578b0a5094SBarry Smith { 15588b0a5094SBarry Smith PetscErrorCode ierr; 15598b0a5094SBarry Smith PetscFunctionBegin; 15608b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15618b0a5094SBarry Smith snes->ops->computepfunction = func; 15628b0a5094SBarry Smith snes->ops->computepjacobian = mfunc; 15638b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 15648b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 15658b0a5094SBarry Smith PetscFunctionReturn(0); 15668b0a5094SBarry Smith } 15678b0a5094SBarry Smith 15688b0a5094SBarry Smith #undef __FUNCT__ 1569d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1570d25893d9SBarry Smith /*@C 1571d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1572d25893d9SBarry Smith 1573d25893d9SBarry Smith Logically Collective on SNES 1574d25893d9SBarry Smith 1575d25893d9SBarry Smith Input Parameters: 1576d25893d9SBarry Smith + snes - the SNES context 1577d25893d9SBarry Smith . func - function evaluation routine 1578d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1579d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1580d25893d9SBarry Smith 1581d25893d9SBarry Smith Calling sequence of func: 1582d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1583d25893d9SBarry Smith 1584d25893d9SBarry Smith . f - function vector 1585d25893d9SBarry Smith - ctx - optional user-defined function context 1586d25893d9SBarry Smith 1587d25893d9SBarry Smith Level: intermediate 1588d25893d9SBarry Smith 1589d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1590d25893d9SBarry Smith 1591d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1592d25893d9SBarry Smith @*/ 1593d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1594d25893d9SBarry Smith { 1595d25893d9SBarry Smith PetscFunctionBegin; 1596d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1597d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1598d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1599d25893d9SBarry Smith PetscFunctionReturn(0); 1600d25893d9SBarry Smith } 1601d25893d9SBarry Smith 16023ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 16033ab0aad5SBarry Smith #undef __FUNCT__ 16041096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 16051096aae1SMatthew Knepley /*@C 16061096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 16071096aae1SMatthew Knepley it assumes a zero right hand side. 16081096aae1SMatthew Knepley 16093f9fe445SBarry Smith Logically Collective on SNES 16101096aae1SMatthew Knepley 16111096aae1SMatthew Knepley Input Parameter: 16121096aae1SMatthew Knepley . snes - the SNES context 16131096aae1SMatthew Knepley 16141096aae1SMatthew Knepley Output Parameter: 1615bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 16161096aae1SMatthew Knepley 16171096aae1SMatthew Knepley Level: intermediate 16181096aae1SMatthew Knepley 16191096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 16201096aae1SMatthew Knepley 162185385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 16221096aae1SMatthew Knepley @*/ 16237087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 16241096aae1SMatthew Knepley { 16251096aae1SMatthew Knepley PetscFunctionBegin; 16260700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16271096aae1SMatthew Knepley PetscValidPointer(rhs,2); 162885385478SLisandro Dalcin *rhs = snes->vec_rhs; 16291096aae1SMatthew Knepley PetscFunctionReturn(0); 16301096aae1SMatthew Knepley } 16311096aae1SMatthew Knepley 16321096aae1SMatthew Knepley #undef __FUNCT__ 16334a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 16349b94acceSBarry Smith /*@ 163536851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 16369b94acceSBarry Smith SNESSetFunction(). 16379b94acceSBarry Smith 1638c7afd0dbSLois Curfman McInnes Collective on SNES 1639c7afd0dbSLois Curfman McInnes 16409b94acceSBarry Smith Input Parameters: 1641c7afd0dbSLois Curfman McInnes + snes - the SNES context 1642c7afd0dbSLois Curfman McInnes - x - input vector 16439b94acceSBarry Smith 16449b94acceSBarry Smith Output Parameter: 16453638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 16469b94acceSBarry Smith 16471bffabb2SLois Curfman McInnes Notes: 164836851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 164936851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 165036851e7fSLois Curfman McInnes themselves. 165136851e7fSLois Curfman McInnes 165236851e7fSLois Curfman McInnes Level: developer 165336851e7fSLois Curfman McInnes 16549b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 16559b94acceSBarry Smith 1656a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 16579b94acceSBarry Smith @*/ 16587087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 16599b94acceSBarry Smith { 1660dfbe8321SBarry Smith PetscErrorCode ierr; 16616cab3a1bSJed Brown DM dm; 16626cab3a1bSJed Brown SNESDM sdm; 16639b94acceSBarry Smith 16643a40ed3dSBarry Smith PetscFunctionBegin; 16650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16660700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 16670700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1668c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1669c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 16704ec14c9cSBarry Smith VecValidValues(x,2,PETSC_TRUE); 1671184914b5SBarry Smith 16726cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 16736cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 1674d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 16756cab3a1bSJed Brown if (sdm->computefunction) { 1676d64ed03dSBarry Smith PetscStackPush("SNES user function"); 16776cab3a1bSJed Brown ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 1678d64ed03dSBarry Smith PetscStackPop; 167973250ac0SBarry Smith } else if (snes->dm) { 1680644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1681c90fad12SPeter Brune } else if (snes->vec_rhs) { 1682c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1683644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 168485385478SLisandro Dalcin if (snes->vec_rhs) { 168585385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 16863ab0aad5SBarry Smith } 1687ae3c334cSLois Curfman McInnes snes->nfuncs++; 1688d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 16894ec14c9cSBarry Smith VecValidValues(y,3,PETSC_FALSE); 16903a40ed3dSBarry Smith PetscFunctionReturn(0); 16919b94acceSBarry Smith } 16929b94acceSBarry Smith 16934a2ae208SSatish Balay #undef __FUNCT__ 1694646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1695c79ef259SPeter Brune /*@ 1696c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1697c79ef259SPeter Brune SNESSetGS(). 1698c79ef259SPeter Brune 1699c79ef259SPeter Brune Collective on SNES 1700c79ef259SPeter Brune 1701c79ef259SPeter Brune Input Parameters: 1702c79ef259SPeter Brune + snes - the SNES context 1703c79ef259SPeter Brune . x - input vector 1704c79ef259SPeter Brune - b - rhs vector 1705c79ef259SPeter Brune 1706c79ef259SPeter Brune Output Parameter: 1707c79ef259SPeter Brune . x - new solution vector 1708c79ef259SPeter Brune 1709c79ef259SPeter Brune Notes: 1710c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1711c79ef259SPeter Brune implementations, so most users would not generally call this routine 1712c79ef259SPeter Brune themselves. 1713c79ef259SPeter Brune 1714c79ef259SPeter Brune Level: developer 1715c79ef259SPeter Brune 1716c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1717c79ef259SPeter Brune 1718c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1719c79ef259SPeter Brune @*/ 1720646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1721646217ecSPeter Brune { 1722646217ecSPeter Brune PetscErrorCode ierr; 172389b92e6fSPeter Brune PetscInt i; 17246cab3a1bSJed Brown DM dm; 17256cab3a1bSJed Brown SNESDM sdm; 1726646217ecSPeter Brune 1727646217ecSPeter Brune PetscFunctionBegin; 1728646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1729646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1730646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1731646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 1732646217ecSPeter Brune if(b) PetscCheckSameComm(snes,1,b,3); 17334ec14c9cSBarry Smith if (b) VecValidValues(b,2,PETSC_TRUE); 1734701cf23dSPeter Brune ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 17356cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 17366cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 17376cab3a1bSJed Brown if (sdm->computegs) { 173889b92e6fSPeter Brune for (i = 0; i < snes->gssweeps; i++) { 1739646217ecSPeter Brune PetscStackPush("SNES user GS"); 17406cab3a1bSJed Brown ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 1741646217ecSPeter Brune PetscStackPop; 174289b92e6fSPeter Brune } 1743646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 1744701cf23dSPeter Brune ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 17454ec14c9cSBarry Smith VecValidValues(x,3,PETSC_FALSE); 1746646217ecSPeter Brune PetscFunctionReturn(0); 1747646217ecSPeter Brune } 1748646217ecSPeter Brune 1749646217ecSPeter Brune 1750646217ecSPeter Brune #undef __FUNCT__ 17514a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 175262fef451SLois Curfman McInnes /*@ 175362fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 175462fef451SLois Curfman McInnes set with SNESSetJacobian(). 175562fef451SLois Curfman McInnes 1756c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1757c7afd0dbSLois Curfman McInnes 175862fef451SLois Curfman McInnes Input Parameters: 1759c7afd0dbSLois Curfman McInnes + snes - the SNES context 1760c7afd0dbSLois Curfman McInnes - x - input vector 176162fef451SLois Curfman McInnes 176262fef451SLois Curfman McInnes Output Parameters: 1763c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 176462fef451SLois Curfman McInnes . B - optional preconditioning matrix 17652b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1766fee21e36SBarry Smith 1767e35cf81dSBarry Smith Options Database Keys: 1768e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1769693365a8SJed Brown . -snes_lag_jacobian <lag> 1770693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1771693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1772693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 17734c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1774c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 1775c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 1776c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 1777c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 1778c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 17794c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 1780c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 1781c01495d3SJed Brown 1782e35cf81dSBarry Smith 178362fef451SLois Curfman McInnes Notes: 178462fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 178562fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 178662fef451SLois Curfman McInnes 178794b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1788dc5a77f8SLois Curfman McInnes flag parameter. 178962fef451SLois Curfman McInnes 179036851e7fSLois Curfman McInnes Level: developer 179136851e7fSLois Curfman McInnes 179262fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 179362fef451SLois Curfman McInnes 1794e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 179562fef451SLois Curfman McInnes @*/ 17967087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 17979b94acceSBarry Smith { 1798dfbe8321SBarry Smith PetscErrorCode ierr; 1799ace3abfcSBarry Smith PetscBool flag; 18006cab3a1bSJed Brown DM dm; 18016cab3a1bSJed Brown SNESDM sdm; 18023a40ed3dSBarry Smith 18033a40ed3dSBarry Smith PetscFunctionBegin; 18040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 18050700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 18064482741eSBarry Smith PetscValidPointer(flg,5); 1807c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 18084ec14c9cSBarry Smith VecValidValues(X,2,PETSC_TRUE); 18096cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18106cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 18116cab3a1bSJed Brown if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 1812ebd3b9afSBarry Smith 1813ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1814ebd3b9afSBarry Smith 1815fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 1816fe3ffe1eSBarry Smith snes->lagjacobian = -1; 1817fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1818fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 1819e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1820e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1821ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1822ebd3b9afSBarry Smith if (flag) { 1823ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1824ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1825ebd3b9afSBarry Smith } 1826e35cf81dSBarry Smith PetscFunctionReturn(0); 1827e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1828e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1829e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1830ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1831ebd3b9afSBarry Smith if (flag) { 1832ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1833ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1834ebd3b9afSBarry Smith } 1835e35cf81dSBarry Smith PetscFunctionReturn(0); 1836e35cf81dSBarry Smith } 1837e35cf81dSBarry Smith 1838c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 1839e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1840d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 18416cab3a1bSJed Brown ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr); 1842d64ed03dSBarry Smith PetscStackPop; 1843d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1844a8054027SBarry Smith 18453b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 18463b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 18473b4f5425SBarry Smith snes->lagpreconditioner = -1; 18483b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 1849a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1850a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 1851a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 1852a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1853a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 1854a8054027SBarry Smith } 1855a8054027SBarry Smith 18566d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 18570700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 18580700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 1859693365a8SJed Brown { 1860693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 1861693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 1862693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 1863693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 1864693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 1865693365a8SJed Brown if (flag || flag_draw || flag_contour) { 1866693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 1867693365a8SJed Brown MatStructure mstruct; 1868693365a8SJed Brown PetscViewer vdraw,vstdout; 18696b3a5b13SJed Brown PetscBool flg; 1870693365a8SJed Brown if (flag_operator) { 1871693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 1872693365a8SJed Brown Bexp = Bexp_mine; 1873693365a8SJed Brown } else { 1874693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 1875693365a8SJed Brown ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 1876693365a8SJed Brown if (flg) Bexp = *B; 1877693365a8SJed Brown else { 1878693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 1879693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 1880693365a8SJed Brown Bexp = Bexp_mine; 1881693365a8SJed Brown } 1882693365a8SJed Brown } 1883693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 1884693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 1885693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 1886693365a8SJed Brown if (flag_draw || flag_contour) { 1887693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 1888693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 1889693365a8SJed Brown } else vdraw = PETSC_NULL; 1890693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 1891693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 1892693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 1893693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 1894693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1895693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 1896693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1897693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 1898693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1899693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 1900693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 1901693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 1902693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 1903693365a8SJed Brown } 1904693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 1905693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 1906693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 1907693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 1908693365a8SJed Brown } 1909693365a8SJed Brown } 19104c30e9fbSJed Brown { 19116719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 19126719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 19134c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 19146719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 19154c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 19164c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 19176719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 19186719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 19196719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 19206719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 19214c30e9fbSJed Brown Mat Bfd; 19224c30e9fbSJed Brown MatStructure mstruct; 19234c30e9fbSJed Brown PetscViewer vdraw,vstdout; 19244c30e9fbSJed Brown ISColoring iscoloring; 19254c30e9fbSJed Brown MatFDColoring matfdcoloring; 19264c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 19274c30e9fbSJed Brown void *funcctx; 19286719d8e4SJed Brown PetscReal norm1,norm2,normmax; 19294c30e9fbSJed Brown 19304c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 19314c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 19324c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 19334c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 19344c30e9fbSJed Brown 19354c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 19364c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 19374c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 19384c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 19394c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 19404c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 19414c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 19424c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 19434c30e9fbSJed Brown 19444c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 19454c30e9fbSJed Brown if (flag_draw || flag_contour) { 19464c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 19474c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 19484c30e9fbSJed Brown } else vdraw = PETSC_NULL; 19494c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 19506719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 19514c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 19524c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 19536719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 19544c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 19554c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 19564c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 19576719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 19584c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 19596719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 19606719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 19614c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 19624c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 19634c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 19644c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 19654c30e9fbSJed Brown } 19664c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 19676719d8e4SJed Brown 19686719d8e4SJed Brown if (flag_threshold) { 19696719d8e4SJed Brown PetscInt bs,rstart,rend,i; 19706719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 19716719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 19726719d8e4SJed Brown for (i=rstart; i<rend; i++) { 19736719d8e4SJed Brown const PetscScalar *ba,*ca; 19746719d8e4SJed Brown const PetscInt *bj,*cj; 19756719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 19766719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 19776719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 19786719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 19796719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 19806719d8e4SJed Brown for (j=0; j<bn; j++) { 19816719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 19826719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 19836719d8e4SJed Brown maxentrycol = bj[j]; 19846719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 19856719d8e4SJed Brown } 19866719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 19876719d8e4SJed Brown maxdiffcol = bj[j]; 19886719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 19896719d8e4SJed Brown } 19906719d8e4SJed Brown if (rdiff > maxrdiff) { 19916719d8e4SJed Brown maxrdiffcol = bj[j]; 19926719d8e4SJed Brown maxrdiff = rdiff; 19936719d8e4SJed Brown } 19946719d8e4SJed Brown } 19956719d8e4SJed Brown if (maxrdiff > 1) { 19966719d8e4SJed 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); 19976719d8e4SJed Brown for (j=0; j<bn; j++) { 19986719d8e4SJed Brown PetscReal rdiff; 19996719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 20006719d8e4SJed Brown if (rdiff > 1) { 20016719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 20026719d8e4SJed Brown } 20036719d8e4SJed Brown } 20046719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 20056719d8e4SJed Brown } 20066719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 20076719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 20086719d8e4SJed Brown } 20096719d8e4SJed Brown } 20104c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 20114c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 20124c30e9fbSJed Brown } 20134c30e9fbSJed Brown } 20143a40ed3dSBarry Smith PetscFunctionReturn(0); 20159b94acceSBarry Smith } 20169b94acceSBarry Smith 20174a2ae208SSatish Balay #undef __FUNCT__ 20184a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 20199b94acceSBarry Smith /*@C 20209b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2021044dda88SLois Curfman McInnes location to store the matrix. 20229b94acceSBarry Smith 20233f9fe445SBarry Smith Logically Collective on SNES and Mat 2024c7afd0dbSLois Curfman McInnes 20259b94acceSBarry Smith Input Parameters: 2026c7afd0dbSLois Curfman McInnes + snes - the SNES context 20279b94acceSBarry Smith . A - Jacobian matrix 20289b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 2029efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 2030c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 2031efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 20329b94acceSBarry Smith 20339b94acceSBarry Smith Calling sequence of func: 20348d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 20359b94acceSBarry Smith 2036c7afd0dbSLois Curfman McInnes + x - input vector 20379b94acceSBarry Smith . A - Jacobian matrix 20389b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 2039ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 20402b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 2041c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 20429b94acceSBarry Smith 20439b94acceSBarry Smith Notes: 204494b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 20452cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 2046ac21db08SLois Curfman McInnes 2047ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 20489b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 20499b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 20509b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 20519b94acceSBarry Smith throughout the global iterations. 20529b94acceSBarry Smith 205316913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 205416913363SBarry Smith each matrix. 205516913363SBarry Smith 2056a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 2057a8a26c1eSJed Brown must be a MatFDColoring. 2058a8a26c1eSJed Brown 2059c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2060c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2061c3cc8fd1SJed Brown 206236851e7fSLois Curfman McInnes Level: beginner 206336851e7fSLois Curfman McInnes 20649b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 20659b94acceSBarry Smith 20663ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 20679b94acceSBarry Smith @*/ 20687087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 20699b94acceSBarry Smith { 2070dfbe8321SBarry Smith PetscErrorCode ierr; 20716cab3a1bSJed Brown DM dm; 20723a7fca6bSBarry Smith 20733a40ed3dSBarry Smith PetscFunctionBegin; 20740700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 20750700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 20760700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 2077c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 207806975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 20796cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 20806cab3a1bSJed Brown ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr); 20813a7fca6bSBarry Smith if (A) { 20827dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 20836bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 20849b94acceSBarry Smith snes->jacobian = A; 20853a7fca6bSBarry Smith } 20863a7fca6bSBarry Smith if (B) { 20877dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 20886bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 20899b94acceSBarry Smith snes->jacobian_pre = B; 20903a7fca6bSBarry Smith } 20913a40ed3dSBarry Smith PetscFunctionReturn(0); 20929b94acceSBarry Smith } 209362fef451SLois Curfman McInnes 20944a2ae208SSatish Balay #undef __FUNCT__ 20954a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 2096c2aafc4cSSatish Balay /*@C 2097b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2098b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2099b4fd4287SBarry Smith 2100c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2101c7afd0dbSLois Curfman McInnes 2102b4fd4287SBarry Smith Input Parameter: 2103b4fd4287SBarry Smith . snes - the nonlinear solver context 2104b4fd4287SBarry Smith 2105b4fd4287SBarry Smith Output Parameters: 2106c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 2107b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 210870e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 210970e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 2110fee21e36SBarry Smith 211136851e7fSLois Curfman McInnes Level: advanced 211236851e7fSLois Curfman McInnes 2113b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 2114b4fd4287SBarry Smith @*/ 21157087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 2116b4fd4287SBarry Smith { 21176cab3a1bSJed Brown PetscErrorCode ierr; 21186cab3a1bSJed Brown DM dm; 21196cab3a1bSJed Brown SNESDM sdm; 21206cab3a1bSJed Brown 21213a40ed3dSBarry Smith PetscFunctionBegin; 21220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2123b4fd4287SBarry Smith if (A) *A = snes->jacobian; 2124b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 21256cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 21266cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 21276cab3a1bSJed Brown if (func) *func = sdm->computejacobian; 21286cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 21293a40ed3dSBarry Smith PetscFunctionReturn(0); 2130b4fd4287SBarry Smith } 2131b4fd4287SBarry Smith 21329b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 21339b94acceSBarry Smith 21344a2ae208SSatish Balay #undef __FUNCT__ 21354a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 21369b94acceSBarry Smith /*@ 21379b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2138272ac6f2SLois Curfman McInnes of a nonlinear solver. 21399b94acceSBarry Smith 2140fee21e36SBarry Smith Collective on SNES 2141fee21e36SBarry Smith 2142c7afd0dbSLois Curfman McInnes Input Parameters: 214370e92668SMatthew Knepley . snes - the SNES context 2144c7afd0dbSLois Curfman McInnes 2145272ac6f2SLois Curfman McInnes Notes: 2146272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2147272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2148272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2149272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2150272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2151272ac6f2SLois Curfman McInnes 215236851e7fSLois Curfman McInnes Level: advanced 215336851e7fSLois Curfman McInnes 21549b94acceSBarry Smith .keywords: SNES, nonlinear, setup 21559b94acceSBarry Smith 21569b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 21579b94acceSBarry Smith @*/ 21587087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 21599b94acceSBarry Smith { 2160dfbe8321SBarry Smith PetscErrorCode ierr; 21616cab3a1bSJed Brown DM dm; 21626cab3a1bSJed Brown SNESDM sdm; 21633a40ed3dSBarry Smith 21643a40ed3dSBarry Smith PetscFunctionBegin; 21650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 21664dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 21679b94acceSBarry Smith 21687adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 216985385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 217085385478SLisandro Dalcin } 217185385478SLisandro Dalcin 2172a63bb30eSJed Brown ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 217317186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 217458c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 217558c9b817SLisandro Dalcin 217658c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 217758c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 217858c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 217958c9b817SLisandro Dalcin } 218058c9b817SLisandro Dalcin 21816cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 21826cab3a1bSJed Brown ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */ 21836cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 21846cab3a1bSJed Brown if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc"); 21856cab3a1bSJed Brown if (!snes->vec_func) { 21866cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2187214df951SJed Brown } 2188efd51863SBarry Smith 2189b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 2190b710008aSBarry Smith 21919e764e56SPeter Brune if (!snes->linesearch) {ierr = SNESGetPetscLineSearch(snes, &snes->linesearch);} 21929e764e56SPeter Brune 2193d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 2194d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2195d25893d9SBarry Smith } 2196d25893d9SBarry Smith 2197410397dcSLisandro Dalcin if (snes->ops->setup) { 2198410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2199410397dcSLisandro Dalcin } 220058c9b817SLisandro Dalcin 22017aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 22023a40ed3dSBarry Smith PetscFunctionReturn(0); 22039b94acceSBarry Smith } 22049b94acceSBarry Smith 22054a2ae208SSatish Balay #undef __FUNCT__ 220637596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 220737596af1SLisandro Dalcin /*@ 220837596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 220937596af1SLisandro Dalcin 221037596af1SLisandro Dalcin Collective on SNES 221137596af1SLisandro Dalcin 221237596af1SLisandro Dalcin Input Parameter: 221337596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 221437596af1SLisandro Dalcin 2215d25893d9SBarry Smith Level: intermediate 2216d25893d9SBarry Smith 2217d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 221837596af1SLisandro Dalcin 221937596af1SLisandro Dalcin .keywords: SNES, destroy 222037596af1SLisandro Dalcin 222137596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 222237596af1SLisandro Dalcin @*/ 222337596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 222437596af1SLisandro Dalcin { 222537596af1SLisandro Dalcin PetscErrorCode ierr; 222637596af1SLisandro Dalcin 222737596af1SLisandro Dalcin PetscFunctionBegin; 222837596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2229d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2230d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2231d25893d9SBarry Smith snes->user = PETSC_NULL; 2232d25893d9SBarry Smith } 22338a23116dSBarry Smith if (snes->pc) { 22348a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 22358a23116dSBarry Smith } 22368a23116dSBarry Smith 223737596af1SLisandro Dalcin if (snes->ops->reset) { 223837596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 223937596af1SLisandro Dalcin } 22409e764e56SPeter Brune if (snes->ksp) { 22419e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 22429e764e56SPeter Brune } 22439e764e56SPeter Brune 22449e764e56SPeter Brune if (snes->linesearch) { 22459e764e56SPeter Brune ierr = PetscLineSearchReset(snes->linesearch);CHKERRQ(ierr); 22469e764e56SPeter Brune } 22479e764e56SPeter Brune 22486bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 22496bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 22506bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 22516bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 22526bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 22536bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2254c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2255c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 225637596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 225737596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 225837596af1SLisandro Dalcin PetscFunctionReturn(0); 225937596af1SLisandro Dalcin } 226037596af1SLisandro Dalcin 226137596af1SLisandro Dalcin #undef __FUNCT__ 22624a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 226352baeb72SSatish Balay /*@ 22649b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 22659b94acceSBarry Smith with SNESCreate(). 22669b94acceSBarry Smith 2267c7afd0dbSLois Curfman McInnes Collective on SNES 2268c7afd0dbSLois Curfman McInnes 22699b94acceSBarry Smith Input Parameter: 22709b94acceSBarry Smith . snes - the SNES context 22719b94acceSBarry Smith 227236851e7fSLois Curfman McInnes Level: beginner 227336851e7fSLois Curfman McInnes 22749b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 22759b94acceSBarry Smith 227663a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 22779b94acceSBarry Smith @*/ 22786bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 22799b94acceSBarry Smith { 22806849ba73SBarry Smith PetscErrorCode ierr; 22813a40ed3dSBarry Smith 22823a40ed3dSBarry Smith PetscFunctionBegin; 22836bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 22846bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 22856bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2286d4bb536fSBarry Smith 22876bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 22888a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 22896b8b9a38SLisandro Dalcin 2290be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 22916bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 22926bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 22936d4c513bSLisandro Dalcin 22946bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 22956bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 22969e764e56SPeter Brune ierr = PetscLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 22976b8b9a38SLisandro Dalcin 22986bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 22996bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 23006bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 23016b8b9a38SLisandro Dalcin } 23026bf464f9SBarry Smith if ((*snes)->conv_malloc) { 23036bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 23046bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 230558c9b817SLisandro Dalcin } 2306ea630c6eSPeter Brune ierr = PetscViewerDestroy(&(*snes)->ls_monitor);CHKERRQ(ierr); 23076bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2308a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 23093a40ed3dSBarry Smith PetscFunctionReturn(0); 23109b94acceSBarry Smith } 23119b94acceSBarry Smith 23129b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 23139b94acceSBarry Smith 23144a2ae208SSatish Balay #undef __FUNCT__ 2315a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2316a8054027SBarry Smith /*@ 2317a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2318a8054027SBarry Smith 23193f9fe445SBarry Smith Logically Collective on SNES 2320a8054027SBarry Smith 2321a8054027SBarry Smith Input Parameters: 2322a8054027SBarry Smith + snes - the SNES context 2323a8054027SBarry 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 23243b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2325a8054027SBarry Smith 2326a8054027SBarry Smith Options Database Keys: 2327a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2328a8054027SBarry Smith 2329a8054027SBarry Smith Notes: 2330a8054027SBarry Smith The default is 1 2331a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2332a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2333a8054027SBarry Smith 2334a8054027SBarry Smith Level: intermediate 2335a8054027SBarry Smith 2336a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2337a8054027SBarry Smith 2338e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2339a8054027SBarry Smith 2340a8054027SBarry Smith @*/ 23417087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2342a8054027SBarry Smith { 2343a8054027SBarry Smith PetscFunctionBegin; 23440700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2345e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2346e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2347c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2348a8054027SBarry Smith snes->lagpreconditioner = lag; 2349a8054027SBarry Smith PetscFunctionReturn(0); 2350a8054027SBarry Smith } 2351a8054027SBarry Smith 2352a8054027SBarry Smith #undef __FUNCT__ 2353efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2354efd51863SBarry Smith /*@ 2355efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2356efd51863SBarry Smith 2357efd51863SBarry Smith Logically Collective on SNES 2358efd51863SBarry Smith 2359efd51863SBarry Smith Input Parameters: 2360efd51863SBarry Smith + snes - the SNES context 2361efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2362efd51863SBarry Smith 2363efd51863SBarry Smith Options Database Keys: 2364efd51863SBarry Smith . -snes_grid_sequence <steps> 2365efd51863SBarry Smith 2366efd51863SBarry Smith Level: intermediate 2367efd51863SBarry Smith 2368c0df2a02SJed Brown Notes: 2369c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2370c0df2a02SJed Brown 2371efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2372efd51863SBarry Smith 2373efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2374efd51863SBarry Smith 2375efd51863SBarry Smith @*/ 2376efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2377efd51863SBarry Smith { 2378efd51863SBarry Smith PetscFunctionBegin; 2379efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2380efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2381efd51863SBarry Smith snes->gridsequence = steps; 2382efd51863SBarry Smith PetscFunctionReturn(0); 2383efd51863SBarry Smith } 2384efd51863SBarry Smith 2385efd51863SBarry Smith #undef __FUNCT__ 2386a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2387a8054027SBarry Smith /*@ 2388a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2389a8054027SBarry Smith 23903f9fe445SBarry Smith Not Collective 2391a8054027SBarry Smith 2392a8054027SBarry Smith Input Parameter: 2393a8054027SBarry Smith . snes - the SNES context 2394a8054027SBarry Smith 2395a8054027SBarry Smith Output Parameter: 2396a8054027SBarry 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 23973b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2398a8054027SBarry Smith 2399a8054027SBarry Smith Options Database Keys: 2400a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2401a8054027SBarry Smith 2402a8054027SBarry Smith Notes: 2403a8054027SBarry Smith The default is 1 2404a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2405a8054027SBarry Smith 2406a8054027SBarry Smith Level: intermediate 2407a8054027SBarry Smith 2408a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2409a8054027SBarry Smith 2410a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2411a8054027SBarry Smith 2412a8054027SBarry Smith @*/ 24137087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2414a8054027SBarry Smith { 2415a8054027SBarry Smith PetscFunctionBegin; 24160700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2417a8054027SBarry Smith *lag = snes->lagpreconditioner; 2418a8054027SBarry Smith PetscFunctionReturn(0); 2419a8054027SBarry Smith } 2420a8054027SBarry Smith 2421a8054027SBarry Smith #undef __FUNCT__ 2422e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2423e35cf81dSBarry Smith /*@ 2424e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2425e35cf81dSBarry Smith often the preconditioner is rebuilt. 2426e35cf81dSBarry Smith 24273f9fe445SBarry Smith Logically Collective on SNES 2428e35cf81dSBarry Smith 2429e35cf81dSBarry Smith Input Parameters: 2430e35cf81dSBarry Smith + snes - the SNES context 2431e35cf81dSBarry 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 2432fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2433e35cf81dSBarry Smith 2434e35cf81dSBarry Smith Options Database Keys: 2435e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2436e35cf81dSBarry Smith 2437e35cf81dSBarry Smith Notes: 2438e35cf81dSBarry Smith The default is 1 2439e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2440fe3ffe1eSBarry 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 2441fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2442e35cf81dSBarry Smith 2443e35cf81dSBarry Smith Level: intermediate 2444e35cf81dSBarry Smith 2445e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2446e35cf81dSBarry Smith 2447e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2448e35cf81dSBarry Smith 2449e35cf81dSBarry Smith @*/ 24507087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2451e35cf81dSBarry Smith { 2452e35cf81dSBarry Smith PetscFunctionBegin; 24530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2454e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2455e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2456c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2457e35cf81dSBarry Smith snes->lagjacobian = lag; 2458e35cf81dSBarry Smith PetscFunctionReturn(0); 2459e35cf81dSBarry Smith } 2460e35cf81dSBarry Smith 2461e35cf81dSBarry Smith #undef __FUNCT__ 2462e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2463e35cf81dSBarry Smith /*@ 2464e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2465e35cf81dSBarry Smith 24663f9fe445SBarry Smith Not Collective 2467e35cf81dSBarry Smith 2468e35cf81dSBarry Smith Input Parameter: 2469e35cf81dSBarry Smith . snes - the SNES context 2470e35cf81dSBarry Smith 2471e35cf81dSBarry Smith Output Parameter: 2472e35cf81dSBarry 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 2473e35cf81dSBarry Smith the Jacobian is built etc. 2474e35cf81dSBarry Smith 2475e35cf81dSBarry Smith Options Database Keys: 2476e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2477e35cf81dSBarry Smith 2478e35cf81dSBarry Smith Notes: 2479e35cf81dSBarry Smith The default is 1 2480e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2481e35cf81dSBarry Smith 2482e35cf81dSBarry Smith Level: intermediate 2483e35cf81dSBarry Smith 2484e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2485e35cf81dSBarry Smith 2486e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2487e35cf81dSBarry Smith 2488e35cf81dSBarry Smith @*/ 24897087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2490e35cf81dSBarry Smith { 2491e35cf81dSBarry Smith PetscFunctionBegin; 24920700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2493e35cf81dSBarry Smith *lag = snes->lagjacobian; 2494e35cf81dSBarry Smith PetscFunctionReturn(0); 2495e35cf81dSBarry Smith } 2496e35cf81dSBarry Smith 2497e35cf81dSBarry Smith #undef __FUNCT__ 24984a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 24999b94acceSBarry Smith /*@ 2500d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 25019b94acceSBarry Smith 25023f9fe445SBarry Smith Logically Collective on SNES 2503c7afd0dbSLois Curfman McInnes 25049b94acceSBarry Smith Input Parameters: 2505c7afd0dbSLois Curfman McInnes + snes - the SNES context 250670441072SBarry Smith . abstol - absolute convergence tolerance 250733174efeSLois Curfman McInnes . rtol - relative convergence tolerance 250833174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 250933174efeSLois Curfman McInnes of the change in the solution between steps 251033174efeSLois Curfman McInnes . maxit - maximum number of iterations 2511c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2512fee21e36SBarry Smith 251333174efeSLois Curfman McInnes Options Database Keys: 251470441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2515c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2516c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2517c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2518c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 25199b94acceSBarry Smith 2520d7a720efSLois Curfman McInnes Notes: 25219b94acceSBarry Smith The default maximum number of iterations is 50. 25229b94acceSBarry Smith The default maximum number of function evaluations is 1000. 25239b94acceSBarry Smith 252436851e7fSLois Curfman McInnes Level: intermediate 252536851e7fSLois Curfman McInnes 252633174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 25279b94acceSBarry Smith 25282492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 25299b94acceSBarry Smith @*/ 25307087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 25319b94acceSBarry Smith { 25323a40ed3dSBarry Smith PetscFunctionBegin; 25330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2534c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2535c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2536c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2537c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2538c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2539c5eb9154SBarry Smith 2540ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2541ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2542ab54825eSJed Brown snes->abstol = abstol; 2543ab54825eSJed Brown } 2544ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2545ab54825eSJed 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); 2546ab54825eSJed Brown snes->rtol = rtol; 2547ab54825eSJed Brown } 2548ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2549ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2550ab54825eSJed Brown snes->xtol = stol; 2551ab54825eSJed Brown } 2552ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2553ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2554ab54825eSJed Brown snes->max_its = maxit; 2555ab54825eSJed Brown } 2556ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2557ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2558ab54825eSJed Brown snes->max_funcs = maxf; 2559ab54825eSJed Brown } 25603a40ed3dSBarry Smith PetscFunctionReturn(0); 25619b94acceSBarry Smith } 25629b94acceSBarry Smith 25634a2ae208SSatish Balay #undef __FUNCT__ 25644a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 25659b94acceSBarry Smith /*@ 256633174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 256733174efeSLois Curfman McInnes 2568c7afd0dbSLois Curfman McInnes Not Collective 2569c7afd0dbSLois Curfman McInnes 257033174efeSLois Curfman McInnes Input Parameters: 2571c7afd0dbSLois Curfman McInnes + snes - the SNES context 257285385478SLisandro Dalcin . atol - absolute convergence tolerance 257333174efeSLois Curfman McInnes . rtol - relative convergence tolerance 257433174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 257533174efeSLois Curfman McInnes of the change in the solution between steps 257633174efeSLois Curfman McInnes . maxit - maximum number of iterations 2577c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2578fee21e36SBarry Smith 257933174efeSLois Curfman McInnes Notes: 258033174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 258133174efeSLois Curfman McInnes 258236851e7fSLois Curfman McInnes Level: intermediate 258336851e7fSLois Curfman McInnes 258433174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 258533174efeSLois Curfman McInnes 258633174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 258733174efeSLois Curfman McInnes @*/ 25887087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 258933174efeSLois Curfman McInnes { 25903a40ed3dSBarry Smith PetscFunctionBegin; 25910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 259285385478SLisandro Dalcin if (atol) *atol = snes->abstol; 259333174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 259433174efeSLois Curfman McInnes if (stol) *stol = snes->xtol; 259533174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 259633174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 25973a40ed3dSBarry Smith PetscFunctionReturn(0); 259833174efeSLois Curfman McInnes } 259933174efeSLois Curfman McInnes 26004a2ae208SSatish Balay #undef __FUNCT__ 26014a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 260233174efeSLois Curfman McInnes /*@ 26039b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 26049b94acceSBarry Smith 26053f9fe445SBarry Smith Logically Collective on SNES 2606fee21e36SBarry Smith 2607c7afd0dbSLois Curfman McInnes Input Parameters: 2608c7afd0dbSLois Curfman McInnes + snes - the SNES context 2609c7afd0dbSLois Curfman McInnes - tol - tolerance 2610c7afd0dbSLois Curfman McInnes 26119b94acceSBarry Smith Options Database Key: 2612c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 26139b94acceSBarry Smith 261436851e7fSLois Curfman McInnes Level: intermediate 261536851e7fSLois Curfman McInnes 26169b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 26179b94acceSBarry Smith 26182492ecdbSBarry Smith .seealso: SNESSetTolerances() 26199b94acceSBarry Smith @*/ 26207087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 26219b94acceSBarry Smith { 26223a40ed3dSBarry Smith PetscFunctionBegin; 26230700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2624c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 26259b94acceSBarry Smith snes->deltatol = tol; 26263a40ed3dSBarry Smith PetscFunctionReturn(0); 26279b94acceSBarry Smith } 26289b94acceSBarry Smith 2629df9fa365SBarry Smith /* 2630df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2631df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2632df9fa365SBarry Smith macros instead of functions 2633df9fa365SBarry Smith */ 26344a2ae208SSatish Balay #undef __FUNCT__ 2635a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 26367087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2637ce1608b8SBarry Smith { 2638dfbe8321SBarry Smith PetscErrorCode ierr; 2639ce1608b8SBarry Smith 2640ce1608b8SBarry Smith PetscFunctionBegin; 26410700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2642a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2643ce1608b8SBarry Smith PetscFunctionReturn(0); 2644ce1608b8SBarry Smith } 2645ce1608b8SBarry Smith 26464a2ae208SSatish Balay #undef __FUNCT__ 2647a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 26487087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2649df9fa365SBarry Smith { 2650dfbe8321SBarry Smith PetscErrorCode ierr; 2651df9fa365SBarry Smith 2652df9fa365SBarry Smith PetscFunctionBegin; 2653a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2654df9fa365SBarry Smith PetscFunctionReturn(0); 2655df9fa365SBarry Smith } 2656df9fa365SBarry Smith 26574a2ae208SSatish Balay #undef __FUNCT__ 2658a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 26596bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2660df9fa365SBarry Smith { 2661dfbe8321SBarry Smith PetscErrorCode ierr; 2662df9fa365SBarry Smith 2663df9fa365SBarry Smith PetscFunctionBegin; 2664a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2665df9fa365SBarry Smith PetscFunctionReturn(0); 2666df9fa365SBarry Smith } 2667df9fa365SBarry Smith 26687087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2669b271bb04SBarry Smith #undef __FUNCT__ 2670b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 26717087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2672b271bb04SBarry Smith { 2673b271bb04SBarry Smith PetscDrawLG lg; 2674b271bb04SBarry Smith PetscErrorCode ierr; 2675b271bb04SBarry Smith PetscReal x,y,per; 2676b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2677b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2678b271bb04SBarry Smith PetscDraw draw; 2679b271bb04SBarry Smith PetscFunctionBegin; 2680b271bb04SBarry Smith if (!monctx) { 2681b271bb04SBarry Smith MPI_Comm comm; 2682b271bb04SBarry Smith 2683b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2684b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2685b271bb04SBarry Smith } 2686b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2687b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2688b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2689b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2690b271bb04SBarry Smith x = (PetscReal) n; 2691b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2692b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2693b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2694b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2695b271bb04SBarry Smith } 2696b271bb04SBarry Smith 2697b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2698b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2699b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2700b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2701b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2702b271bb04SBarry Smith x = (PetscReal) n; 2703b271bb04SBarry Smith y = 100.0*per; 2704b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2705b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2706b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2707b271bb04SBarry Smith } 2708b271bb04SBarry Smith 2709b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2710b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2711b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2712b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2713b271bb04SBarry Smith x = (PetscReal) n; 2714b271bb04SBarry Smith y = (prev - rnorm)/prev; 2715b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2716b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2717b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2718b271bb04SBarry Smith } 2719b271bb04SBarry Smith 2720b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2721b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2722b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2723b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2724b271bb04SBarry Smith x = (PetscReal) n; 2725b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2726b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2727b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2728b271bb04SBarry Smith } 2729b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2730b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2731b271bb04SBarry Smith } 2732b271bb04SBarry Smith prev = rnorm; 2733b271bb04SBarry Smith PetscFunctionReturn(0); 2734b271bb04SBarry Smith } 2735b271bb04SBarry Smith 2736b271bb04SBarry Smith #undef __FUNCT__ 2737b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 27387087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2739b271bb04SBarry Smith { 2740b271bb04SBarry Smith PetscErrorCode ierr; 2741b271bb04SBarry Smith 2742b271bb04SBarry Smith PetscFunctionBegin; 2743b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2744b271bb04SBarry Smith PetscFunctionReturn(0); 2745b271bb04SBarry Smith } 2746b271bb04SBarry Smith 2747b271bb04SBarry Smith #undef __FUNCT__ 2748b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 27496bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2750b271bb04SBarry Smith { 2751b271bb04SBarry Smith PetscErrorCode ierr; 2752b271bb04SBarry Smith 2753b271bb04SBarry Smith PetscFunctionBegin; 2754b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2755b271bb04SBarry Smith PetscFunctionReturn(0); 2756b271bb04SBarry Smith } 2757b271bb04SBarry Smith 27587a03ce2fSLisandro Dalcin #undef __FUNCT__ 27597a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 2760228d79bcSJed Brown /*@ 2761228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 2762228d79bcSJed Brown 2763228d79bcSJed Brown Collective on SNES 2764228d79bcSJed Brown 2765228d79bcSJed Brown Input Parameters: 2766228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 2767228d79bcSJed Brown . iter - iteration number 2768228d79bcSJed Brown - rnorm - relative norm of the residual 2769228d79bcSJed Brown 2770228d79bcSJed Brown Notes: 2771228d79bcSJed Brown This routine is called by the SNES implementations. 2772228d79bcSJed Brown It does not typically need to be called by the user. 2773228d79bcSJed Brown 2774228d79bcSJed Brown Level: developer 2775228d79bcSJed Brown 2776228d79bcSJed Brown .seealso: SNESMonitorSet() 2777228d79bcSJed Brown @*/ 27787a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 27797a03ce2fSLisandro Dalcin { 27807a03ce2fSLisandro Dalcin PetscErrorCode ierr; 27817a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 27827a03ce2fSLisandro Dalcin 27837a03ce2fSLisandro Dalcin PetscFunctionBegin; 27847a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 27857a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 27867a03ce2fSLisandro Dalcin } 27877a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 27887a03ce2fSLisandro Dalcin } 27897a03ce2fSLisandro Dalcin 27909b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 27919b94acceSBarry Smith 27924a2ae208SSatish Balay #undef __FUNCT__ 2793a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 27949b94acceSBarry Smith /*@C 2795a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 27969b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 27979b94acceSBarry Smith progress. 27989b94acceSBarry Smith 27993f9fe445SBarry Smith Logically Collective on SNES 2800fee21e36SBarry Smith 2801c7afd0dbSLois Curfman McInnes Input Parameters: 2802c7afd0dbSLois Curfman McInnes + snes - the SNES context 2803c7afd0dbSLois Curfman McInnes . func - monitoring routine 2804b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 2805e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 2806b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 2807b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 28089b94acceSBarry Smith 2809c7afd0dbSLois Curfman McInnes Calling sequence of func: 2810a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2811c7afd0dbSLois Curfman McInnes 2812c7afd0dbSLois Curfman McInnes + snes - the SNES context 2813c7afd0dbSLois Curfman McInnes . its - iteration number 2814c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 281540a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 28169b94acceSBarry Smith 28179665c990SLois Curfman McInnes Options Database Keys: 2818a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 2819a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 2820a6570f20SBarry Smith uses SNESMonitorLGCreate() 2821cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 2822c7afd0dbSLois Curfman McInnes been hardwired into a code by 2823a6570f20SBarry Smith calls to SNESMonitorSet(), but 2824c7afd0dbSLois Curfman McInnes does not cancel those set via 2825c7afd0dbSLois Curfman McInnes the options database. 28269665c990SLois Curfman McInnes 2827639f9d9dSBarry Smith Notes: 28286bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 2829a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 28306bc08f3fSLois Curfman McInnes order in which they were set. 2831639f9d9dSBarry Smith 2832025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 2833025f1a04SBarry Smith 283436851e7fSLois Curfman McInnes Level: intermediate 283536851e7fSLois Curfman McInnes 28369b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 28379b94acceSBarry Smith 2838a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 28399b94acceSBarry Smith @*/ 2840c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 28419b94acceSBarry Smith { 2842b90d0a6eSBarry Smith PetscInt i; 2843649052a6SBarry Smith PetscErrorCode ierr; 2844b90d0a6eSBarry Smith 28453a40ed3dSBarry Smith PetscFunctionBegin; 28460700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 284717186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2848b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 2849649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 2850649052a6SBarry Smith if (monitordestroy) { 2851c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 2852649052a6SBarry Smith } 2853b90d0a6eSBarry Smith PetscFunctionReturn(0); 2854b90d0a6eSBarry Smith } 2855b90d0a6eSBarry Smith } 2856b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 2857b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 2858639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 28593a40ed3dSBarry Smith PetscFunctionReturn(0); 28609b94acceSBarry Smith } 28619b94acceSBarry Smith 28624a2ae208SSatish Balay #undef __FUNCT__ 2863a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 28645cd90555SBarry Smith /*@C 2865a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 28665cd90555SBarry Smith 28673f9fe445SBarry Smith Logically Collective on SNES 2868c7afd0dbSLois Curfman McInnes 28695cd90555SBarry Smith Input Parameters: 28705cd90555SBarry Smith . snes - the SNES context 28715cd90555SBarry Smith 28721a480d89SAdministrator Options Database Key: 2873a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 2874a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 2875c7afd0dbSLois Curfman McInnes set via the options database 28765cd90555SBarry Smith 28775cd90555SBarry Smith Notes: 28785cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 28795cd90555SBarry Smith 288036851e7fSLois Curfman McInnes Level: intermediate 288136851e7fSLois Curfman McInnes 28825cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 28835cd90555SBarry Smith 2884a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 28855cd90555SBarry Smith @*/ 28867087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 28875cd90555SBarry Smith { 2888d952e501SBarry Smith PetscErrorCode ierr; 2889d952e501SBarry Smith PetscInt i; 2890d952e501SBarry Smith 28915cd90555SBarry Smith PetscFunctionBegin; 28920700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2893d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 2894d952e501SBarry Smith if (snes->monitordestroy[i]) { 28953c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 2896d952e501SBarry Smith } 2897d952e501SBarry Smith } 28985cd90555SBarry Smith snes->numbermonitors = 0; 28995cd90555SBarry Smith PetscFunctionReturn(0); 29005cd90555SBarry Smith } 29015cd90555SBarry Smith 29024a2ae208SSatish Balay #undef __FUNCT__ 29034a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 29049b94acceSBarry Smith /*@C 29059b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 29069b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 29079b94acceSBarry Smith 29083f9fe445SBarry Smith Logically Collective on SNES 2909fee21e36SBarry Smith 2910c7afd0dbSLois Curfman McInnes Input Parameters: 2911c7afd0dbSLois Curfman McInnes + snes - the SNES context 2912c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 29137f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 29147f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 29159b94acceSBarry Smith 2916c7afd0dbSLois Curfman McInnes Calling sequence of func: 291706ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 2918c7afd0dbSLois Curfman McInnes 2919c7afd0dbSLois Curfman McInnes + snes - the SNES context 292006ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 2921c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 2922184914b5SBarry Smith . reason - reason for convergence/divergence 2923c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 29244b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 29254b27c08aSLois Curfman McInnes - f - 2-norm of function 29269b94acceSBarry Smith 292736851e7fSLois Curfman McInnes Level: advanced 292836851e7fSLois Curfman McInnes 29299b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 29309b94acceSBarry Smith 293185385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 29329b94acceSBarry Smith @*/ 29337087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 29349b94acceSBarry Smith { 29357f7931b9SBarry Smith PetscErrorCode ierr; 29367f7931b9SBarry Smith 29373a40ed3dSBarry Smith PetscFunctionBegin; 29380700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 293985385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 29407f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 29417f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 29427f7931b9SBarry Smith } 294385385478SLisandro Dalcin snes->ops->converged = func; 29447f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 294585385478SLisandro Dalcin snes->cnvP = cctx; 29463a40ed3dSBarry Smith PetscFunctionReturn(0); 29479b94acceSBarry Smith } 29489b94acceSBarry Smith 29494a2ae208SSatish Balay #undef __FUNCT__ 29504a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 295152baeb72SSatish Balay /*@ 2952184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 2953184914b5SBarry Smith 2954184914b5SBarry Smith Not Collective 2955184914b5SBarry Smith 2956184914b5SBarry Smith Input Parameter: 2957184914b5SBarry Smith . snes - the SNES context 2958184914b5SBarry Smith 2959184914b5SBarry Smith Output Parameter: 29604d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 2961184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 2962184914b5SBarry Smith 2963184914b5SBarry Smith Level: intermediate 2964184914b5SBarry Smith 2965184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 2966184914b5SBarry Smith 2967184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 2968184914b5SBarry Smith 296985385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 2970184914b5SBarry Smith @*/ 29717087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 2972184914b5SBarry Smith { 2973184914b5SBarry Smith PetscFunctionBegin; 29740700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 29754482741eSBarry Smith PetscValidPointer(reason,2); 2976184914b5SBarry Smith *reason = snes->reason; 2977184914b5SBarry Smith PetscFunctionReturn(0); 2978184914b5SBarry Smith } 2979184914b5SBarry Smith 29804a2ae208SSatish Balay #undef __FUNCT__ 29814a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 2982c9005455SLois Curfman McInnes /*@ 2983c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 2984c9005455SLois Curfman McInnes 29853f9fe445SBarry Smith Logically Collective on SNES 2986fee21e36SBarry Smith 2987c7afd0dbSLois Curfman McInnes Input Parameters: 2988c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 29898c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 2990cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 2991758f92a0SBarry Smith . na - size of a and its 299264731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 2993758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 2994c7afd0dbSLois Curfman McInnes 2995308dcc3eSBarry Smith Notes: 2996308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 2997308dcc3eSBarry Smith default array of length 10000 is allocated. 2998308dcc3eSBarry Smith 2999c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 3000c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 3001c9005455SLois Curfman McInnes during the section of code that is being timed. 3002c9005455SLois Curfman McInnes 300336851e7fSLois Curfman McInnes Level: intermediate 300436851e7fSLois Curfman McInnes 3005c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 3006758f92a0SBarry Smith 300708405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 3008758f92a0SBarry Smith 3009c9005455SLois Curfman McInnes @*/ 30107087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 3011c9005455SLois Curfman McInnes { 3012308dcc3eSBarry Smith PetscErrorCode ierr; 3013308dcc3eSBarry Smith 30143a40ed3dSBarry Smith PetscFunctionBegin; 30150700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 30164482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 3017a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 3018308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 3019308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 3020308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 3021308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 3022308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 3023308dcc3eSBarry Smith } 3024c9005455SLois Curfman McInnes snes->conv_hist = a; 3025758f92a0SBarry Smith snes->conv_hist_its = its; 3026758f92a0SBarry Smith snes->conv_hist_max = na; 3027a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 3028758f92a0SBarry Smith snes->conv_hist_reset = reset; 3029758f92a0SBarry Smith PetscFunctionReturn(0); 3030758f92a0SBarry Smith } 3031758f92a0SBarry Smith 3032308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3033c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 3034c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 3035308dcc3eSBarry Smith EXTERN_C_BEGIN 3036308dcc3eSBarry Smith #undef __FUNCT__ 3037308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 3038308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3039308dcc3eSBarry Smith { 3040308dcc3eSBarry Smith mxArray *mat; 3041308dcc3eSBarry Smith PetscInt i; 3042308dcc3eSBarry Smith PetscReal *ar; 3043308dcc3eSBarry Smith 3044308dcc3eSBarry Smith PetscFunctionBegin; 3045308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3046308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3047308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 3048308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 3049308dcc3eSBarry Smith } 3050308dcc3eSBarry Smith PetscFunctionReturn(mat); 3051308dcc3eSBarry Smith } 3052308dcc3eSBarry Smith EXTERN_C_END 3053308dcc3eSBarry Smith #endif 3054308dcc3eSBarry Smith 3055308dcc3eSBarry Smith 30564a2ae208SSatish Balay #undef __FUNCT__ 30574a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 30580c4c9dddSBarry Smith /*@C 3059758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3060758f92a0SBarry Smith 30613f9fe445SBarry Smith Not Collective 3062758f92a0SBarry Smith 3063758f92a0SBarry Smith Input Parameter: 3064758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3065758f92a0SBarry Smith 3066758f92a0SBarry Smith Output Parameters: 3067758f92a0SBarry Smith . a - array to hold history 3068758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3069758f92a0SBarry Smith negative if not converged) for each solve. 3070758f92a0SBarry Smith - na - size of a and its 3071758f92a0SBarry Smith 3072758f92a0SBarry Smith Notes: 3073758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3074758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3075758f92a0SBarry Smith 3076758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3077758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3078758f92a0SBarry Smith during the section of code that is being timed. 3079758f92a0SBarry Smith 3080758f92a0SBarry Smith Level: intermediate 3081758f92a0SBarry Smith 3082758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3083758f92a0SBarry Smith 3084758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3085758f92a0SBarry Smith 3086758f92a0SBarry Smith @*/ 30877087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3088758f92a0SBarry Smith { 3089758f92a0SBarry Smith PetscFunctionBegin; 30900700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3091758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3092758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3093758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 30943a40ed3dSBarry Smith PetscFunctionReturn(0); 3095c9005455SLois Curfman McInnes } 3096c9005455SLois Curfman McInnes 3097e74ef692SMatthew Knepley #undef __FUNCT__ 3098e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 3099ac226902SBarry Smith /*@C 310076b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3101eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 31027e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 310376b2cf59SMatthew Knepley 31043f9fe445SBarry Smith Logically Collective on SNES 310576b2cf59SMatthew Knepley 310676b2cf59SMatthew Knepley Input Parameters: 310776b2cf59SMatthew Knepley . snes - The nonlinear solver context 310876b2cf59SMatthew Knepley . func - The function 310976b2cf59SMatthew Knepley 311076b2cf59SMatthew Knepley Calling sequence of func: 3111b5d30489SBarry Smith . func (SNES snes, PetscInt step); 311276b2cf59SMatthew Knepley 311376b2cf59SMatthew Knepley . step - The current step of the iteration 311476b2cf59SMatthew Knepley 3115fe97e370SBarry Smith Level: advanced 3116fe97e370SBarry Smith 3117fe97e370SBarry 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() 3118fe97e370SBarry Smith This is not used by most users. 311976b2cf59SMatthew Knepley 312076b2cf59SMatthew Knepley .keywords: SNES, update 3121b5d30489SBarry Smith 312285385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 312376b2cf59SMatthew Knepley @*/ 31247087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 312576b2cf59SMatthew Knepley { 312676b2cf59SMatthew Knepley PetscFunctionBegin; 31270700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3128e7788613SBarry Smith snes->ops->update = func; 312976b2cf59SMatthew Knepley PetscFunctionReturn(0); 313076b2cf59SMatthew Knepley } 313176b2cf59SMatthew Knepley 3132e74ef692SMatthew Knepley #undef __FUNCT__ 3133e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 313476b2cf59SMatthew Knepley /*@ 313576b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 313676b2cf59SMatthew Knepley 313776b2cf59SMatthew Knepley Not collective 313876b2cf59SMatthew Knepley 313976b2cf59SMatthew Knepley Input Parameters: 314076b2cf59SMatthew Knepley . snes - The nonlinear solver context 314176b2cf59SMatthew Knepley . step - The current step of the iteration 314276b2cf59SMatthew Knepley 3143205452f4SMatthew Knepley Level: intermediate 3144205452f4SMatthew Knepley 314576b2cf59SMatthew Knepley .keywords: SNES, update 3146a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 314776b2cf59SMatthew Knepley @*/ 31487087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 314976b2cf59SMatthew Knepley { 315076b2cf59SMatthew Knepley PetscFunctionBegin; 315176b2cf59SMatthew Knepley PetscFunctionReturn(0); 315276b2cf59SMatthew Knepley } 315376b2cf59SMatthew Knepley 31544a2ae208SSatish Balay #undef __FUNCT__ 31554a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 31569b94acceSBarry Smith /* 31579b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 31589b94acceSBarry Smith positive parameter delta. 31599b94acceSBarry Smith 31609b94acceSBarry Smith Input Parameters: 3161c7afd0dbSLois Curfman McInnes + snes - the SNES context 31629b94acceSBarry Smith . y - approximate solution of linear system 31639b94acceSBarry Smith . fnorm - 2-norm of current function 3164c7afd0dbSLois Curfman McInnes - delta - trust region size 31659b94acceSBarry Smith 31669b94acceSBarry Smith Output Parameters: 3167c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 31689b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 31699b94acceSBarry Smith region, and exceeds zero otherwise. 3170c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 31719b94acceSBarry Smith 31729b94acceSBarry Smith Note: 31734b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 31749b94acceSBarry Smith is set to be the maximum allowable step size. 31759b94acceSBarry Smith 31769b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 31779b94acceSBarry Smith */ 3178dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 31799b94acceSBarry Smith { 3180064f8208SBarry Smith PetscReal nrm; 3181ea709b57SSatish Balay PetscScalar cnorm; 3182dfbe8321SBarry Smith PetscErrorCode ierr; 31833a40ed3dSBarry Smith 31843a40ed3dSBarry Smith PetscFunctionBegin; 31850700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31860700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3187c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3188184914b5SBarry Smith 3189064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3190064f8208SBarry Smith if (nrm > *delta) { 3191064f8208SBarry Smith nrm = *delta/nrm; 3192064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3193064f8208SBarry Smith cnorm = nrm; 31942dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 31959b94acceSBarry Smith *ynorm = *delta; 31969b94acceSBarry Smith } else { 31979b94acceSBarry Smith *gpnorm = 0.0; 3198064f8208SBarry Smith *ynorm = nrm; 31999b94acceSBarry Smith } 32003a40ed3dSBarry Smith PetscFunctionReturn(0); 32019b94acceSBarry Smith } 32029b94acceSBarry Smith 32034a2ae208SSatish Balay #undef __FUNCT__ 32044a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 32056ce558aeSBarry Smith /*@C 3206f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3207f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 32089b94acceSBarry Smith 3209c7afd0dbSLois Curfman McInnes Collective on SNES 3210c7afd0dbSLois Curfman McInnes 3211b2002411SLois Curfman McInnes Input Parameters: 3212c7afd0dbSLois Curfman McInnes + snes - the SNES context 32133cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 321485385478SLisandro Dalcin - x - the solution vector. 32159b94acceSBarry Smith 3216b2002411SLois Curfman McInnes Notes: 32178ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 32188ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 32198ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 32208ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 32218ddd3da0SLois Curfman McInnes 322236851e7fSLois Curfman McInnes Level: beginner 322336851e7fSLois Curfman McInnes 32249b94acceSBarry Smith .keywords: SNES, nonlinear, solve 32259b94acceSBarry Smith 3226c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 32279b94acceSBarry Smith @*/ 32287087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 32299b94acceSBarry Smith { 3230dfbe8321SBarry Smith PetscErrorCode ierr; 3231ace3abfcSBarry Smith PetscBool flg; 3232eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 3233eabae89aSBarry Smith PetscViewer viewer; 3234efd51863SBarry Smith PetscInt grid; 3235a69afd8bSBarry Smith Vec xcreated = PETSC_NULL; 3236052efed2SBarry Smith 32373a40ed3dSBarry Smith PetscFunctionBegin; 32380700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3239a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3240a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 32410700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 324285385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 324385385478SLisandro Dalcin 3244a69afd8bSBarry Smith if (!x && snes->dm) { 3245a69afd8bSBarry Smith ierr = DMCreateGlobalVector(snes->dm,&xcreated);CHKERRQ(ierr); 3246a69afd8bSBarry Smith x = xcreated; 3247a69afd8bSBarry Smith } 3248a69afd8bSBarry Smith 3249a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3250efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3251efd51863SBarry Smith 325285385478SLisandro Dalcin /* set solution vector */ 3253efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 32546bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 325585385478SLisandro Dalcin snes->vec_sol = x; 325685385478SLisandro Dalcin /* set afine vector if provided */ 325785385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 32586bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 325985385478SLisandro Dalcin snes->vec_rhs = b; 326085385478SLisandro Dalcin 326170e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 32623f149594SLisandro Dalcin 32637eee914bSBarry Smith if (!grid) { 32647eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3265d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3266dd568438SSatish Balay } else if (snes->dm) { 3267dd568438SSatish Balay PetscBool ig; 3268dd568438SSatish Balay ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr); 3269dd568438SSatish Balay if (ig) { 32707eee914bSBarry Smith ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr); 32717eee914bSBarry Smith } 3272d25893d9SBarry Smith } 3273dd568438SSatish Balay } 3274d25893d9SBarry Smith 3275abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 327650ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3277d5e45103SBarry Smith 32783f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 32794936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 328085385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 32814936397dSBarry Smith if (snes->domainerror){ 32824936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 32834936397dSBarry Smith snes->domainerror = PETSC_FALSE; 32844936397dSBarry Smith } 328517186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 32863f149594SLisandro Dalcin 32877adad957SLisandro Dalcin ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 3288eabae89aSBarry Smith if (flg && !PetscPreLoadingOn) { 32897adad957SLisandro Dalcin ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 3290eabae89aSBarry Smith ierr = SNESView(snes,viewer);CHKERRQ(ierr); 32916bf464f9SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3292eabae89aSBarry Smith } 3293eabae89aSBarry Smith 329490d69ab7SBarry Smith flg = PETSC_FALSE; 3295acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3296da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 32975968eb51SBarry Smith if (snes->printreason) { 3298a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 32995968eb51SBarry Smith if (snes->reason > 0) { 3300c7e7b494SJed 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); 33015968eb51SBarry Smith } else { 3302c7e7b494SJed 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); 33035968eb51SBarry Smith } 3304a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 33055968eb51SBarry Smith } 33065968eb51SBarry Smith 33078501fc72SJed Brown flg = PETSC_FALSE; 33088501fc72SJed Brown ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 33098501fc72SJed Brown if (flg) { 33108501fc72SJed Brown PetscViewer viewer; 33118501fc72SJed Brown ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 33128501fc72SJed Brown ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 33138501fc72SJed Brown ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 33148501fc72SJed Brown ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 33158501fc72SJed Brown ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 33168501fc72SJed Brown } 33178501fc72SJed Brown 3318e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3319efd51863SBarry Smith if (grid < snes->gridsequence) { 3320efd51863SBarry Smith DM fine; 3321efd51863SBarry Smith Vec xnew; 3322efd51863SBarry Smith Mat interp; 3323efd51863SBarry Smith 3324efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3325e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3326efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3327efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3328efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3329efd51863SBarry Smith x = xnew; 3330efd51863SBarry Smith 3331efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3332efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3333efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3334a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3335efd51863SBarry Smith } 3336efd51863SBarry Smith } 3337a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 33383a40ed3dSBarry Smith PetscFunctionReturn(0); 33399b94acceSBarry Smith } 33409b94acceSBarry Smith 33419b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 33429b94acceSBarry Smith 33434a2ae208SSatish Balay #undef __FUNCT__ 33444a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 334582bf6240SBarry Smith /*@C 33464b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 33479b94acceSBarry Smith 3348fee21e36SBarry Smith Collective on SNES 3349fee21e36SBarry Smith 3350c7afd0dbSLois Curfman McInnes Input Parameters: 3351c7afd0dbSLois Curfman McInnes + snes - the SNES context 3352454a90a3SBarry Smith - type - a known method 3353c7afd0dbSLois Curfman McInnes 3354c7afd0dbSLois Curfman McInnes Options Database Key: 3355454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3356c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3357ae12b187SLois Curfman McInnes 33589b94acceSBarry Smith Notes: 3359e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 33604b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3361c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 33624b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3363c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 33649b94acceSBarry Smith 3365ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3366ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3367ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3368ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3369ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3370ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3371ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3372ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3373ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3374b0a32e0cSBarry Smith appropriate method. 337536851e7fSLois Curfman McInnes 337636851e7fSLois Curfman McInnes Level: intermediate 3377a703fe33SLois Curfman McInnes 3378454a90a3SBarry Smith .keywords: SNES, set, type 3379435da068SBarry Smith 3380435da068SBarry Smith .seealso: SNESType, SNESCreate() 3381435da068SBarry Smith 33829b94acceSBarry Smith @*/ 33837087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 33849b94acceSBarry Smith { 3385dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3386ace3abfcSBarry Smith PetscBool match; 33873a40ed3dSBarry Smith 33883a40ed3dSBarry Smith PetscFunctionBegin; 33890700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 33904482741eSBarry Smith PetscValidCharPointer(type,2); 339182bf6240SBarry Smith 33926831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 33930f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 339492ff6ae8SBarry Smith 33954b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3396e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 339775396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 3398b5c23020SJed Brown if (snes->ops->destroy) { 3399b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 3400b5c23020SJed Brown snes->ops->destroy = PETSC_NULL; 3401b5c23020SJed Brown } 340275396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 340375396ef9SLisandro Dalcin snes->ops->setup = 0; 340475396ef9SLisandro Dalcin snes->ops->solve = 0; 340575396ef9SLisandro Dalcin snes->ops->view = 0; 340675396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 340775396ef9SLisandro Dalcin snes->ops->destroy = 0; 340875396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 340975396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3410454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 341103bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 34129fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 34139fb22e1aSBarry Smith if (PetscAMSPublishAll) { 34149fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 34159fb22e1aSBarry Smith } 34169fb22e1aSBarry Smith #endif 34173a40ed3dSBarry Smith PetscFunctionReturn(0); 34189b94acceSBarry Smith } 34199b94acceSBarry Smith 3420a847f771SSatish Balay 34219b94acceSBarry Smith /* --------------------------------------------------------------------- */ 34224a2ae208SSatish Balay #undef __FUNCT__ 34234a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 342452baeb72SSatish Balay /*@ 34259b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3426f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 34279b94acceSBarry Smith 3428fee21e36SBarry Smith Not Collective 3429fee21e36SBarry Smith 343036851e7fSLois Curfman McInnes Level: advanced 343136851e7fSLois Curfman McInnes 34329b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 34339b94acceSBarry Smith 34349b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 34359b94acceSBarry Smith @*/ 34367087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 34379b94acceSBarry Smith { 3438dfbe8321SBarry Smith PetscErrorCode ierr; 343982bf6240SBarry Smith 34403a40ed3dSBarry Smith PetscFunctionBegin; 34411441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 34424c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 34433a40ed3dSBarry Smith PetscFunctionReturn(0); 34449b94acceSBarry Smith } 34459b94acceSBarry Smith 34464a2ae208SSatish Balay #undef __FUNCT__ 34474a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 34489b94acceSBarry Smith /*@C 34499a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 34509b94acceSBarry Smith 3451c7afd0dbSLois Curfman McInnes Not Collective 3452c7afd0dbSLois Curfman McInnes 34539b94acceSBarry Smith Input Parameter: 34544b0e389bSBarry Smith . snes - nonlinear solver context 34559b94acceSBarry Smith 34569b94acceSBarry Smith Output Parameter: 34573a7fca6bSBarry Smith . type - SNES method (a character string) 34589b94acceSBarry Smith 345936851e7fSLois Curfman McInnes Level: intermediate 346036851e7fSLois Curfman McInnes 3461454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 34629b94acceSBarry Smith @*/ 34637087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 34649b94acceSBarry Smith { 34653a40ed3dSBarry Smith PetscFunctionBegin; 34660700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34674482741eSBarry Smith PetscValidPointer(type,2); 34687adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 34693a40ed3dSBarry Smith PetscFunctionReturn(0); 34709b94acceSBarry Smith } 34719b94acceSBarry Smith 34724a2ae208SSatish Balay #undef __FUNCT__ 34734a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 347452baeb72SSatish Balay /*@ 34759b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3476c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 34779b94acceSBarry Smith 3478c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3479c7afd0dbSLois Curfman McInnes 34809b94acceSBarry Smith Input Parameter: 34819b94acceSBarry Smith . snes - the SNES context 34829b94acceSBarry Smith 34839b94acceSBarry Smith Output Parameter: 34849b94acceSBarry Smith . x - the solution 34859b94acceSBarry Smith 348670e92668SMatthew Knepley Level: intermediate 348736851e7fSLois Curfman McInnes 34889b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 34899b94acceSBarry Smith 349085385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 34919b94acceSBarry Smith @*/ 34927087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 34939b94acceSBarry Smith { 34943a40ed3dSBarry Smith PetscFunctionBegin; 34950700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34964482741eSBarry Smith PetscValidPointer(x,2); 349785385478SLisandro Dalcin *x = snes->vec_sol; 349870e92668SMatthew Knepley PetscFunctionReturn(0); 349970e92668SMatthew Knepley } 350070e92668SMatthew Knepley 350170e92668SMatthew Knepley #undef __FUNCT__ 35024a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 350352baeb72SSatish Balay /*@ 35049b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 35059b94acceSBarry Smith stored. 35069b94acceSBarry Smith 3507c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3508c7afd0dbSLois Curfman McInnes 35099b94acceSBarry Smith Input Parameter: 35109b94acceSBarry Smith . snes - the SNES context 35119b94acceSBarry Smith 35129b94acceSBarry Smith Output Parameter: 35139b94acceSBarry Smith . x - the solution update 35149b94acceSBarry Smith 351536851e7fSLois Curfman McInnes Level: advanced 351636851e7fSLois Curfman McInnes 35179b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 35189b94acceSBarry Smith 351985385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 35209b94acceSBarry Smith @*/ 35217087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 35229b94acceSBarry Smith { 35233a40ed3dSBarry Smith PetscFunctionBegin; 35240700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35254482741eSBarry Smith PetscValidPointer(x,2); 352685385478SLisandro Dalcin *x = snes->vec_sol_update; 35273a40ed3dSBarry Smith PetscFunctionReturn(0); 35289b94acceSBarry Smith } 35299b94acceSBarry Smith 35304a2ae208SSatish Balay #undef __FUNCT__ 35314a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 35329b94acceSBarry Smith /*@C 35333638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 35349b94acceSBarry Smith 3535a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 3536c7afd0dbSLois Curfman McInnes 35379b94acceSBarry Smith Input Parameter: 35389b94acceSBarry Smith . snes - the SNES context 35399b94acceSBarry Smith 35409b94acceSBarry Smith Output Parameter: 35417bf4e008SBarry Smith + r - the function (or PETSC_NULL) 354270e92668SMatthew Knepley . func - the function (or PETSC_NULL) 354370e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 35449b94acceSBarry Smith 354536851e7fSLois Curfman McInnes Level: advanced 354636851e7fSLois Curfman McInnes 3547a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 35489b94acceSBarry Smith 35494b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 35509b94acceSBarry Smith @*/ 35517087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 35529b94acceSBarry Smith { 3553a63bb30eSJed Brown PetscErrorCode ierr; 35546cab3a1bSJed Brown DM dm; 3555a63bb30eSJed Brown 35563a40ed3dSBarry Smith PetscFunctionBegin; 35570700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3558a63bb30eSJed Brown if (r) { 3559a63bb30eSJed Brown if (!snes->vec_func) { 3560a63bb30eSJed Brown if (snes->vec_rhs) { 3561a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 3562a63bb30eSJed Brown } else if (snes->vec_sol) { 3563a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 3564a63bb30eSJed Brown } else if (snes->dm) { 3565a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 3566a63bb30eSJed Brown } 3567a63bb30eSJed Brown } 3568a63bb30eSJed Brown *r = snes->vec_func; 3569a63bb30eSJed Brown } 35706cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 35716cab3a1bSJed Brown ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr); 35723a40ed3dSBarry Smith PetscFunctionReturn(0); 35739b94acceSBarry Smith } 35749b94acceSBarry Smith 3575c79ef259SPeter Brune /*@C 3576c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3577c79ef259SPeter Brune 3578c79ef259SPeter Brune Input Parameter: 3579c79ef259SPeter Brune . snes - the SNES context 3580c79ef259SPeter Brune 3581c79ef259SPeter Brune Output Parameter: 3582c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3583c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3584c79ef259SPeter Brune 3585c79ef259SPeter Brune Level: advanced 3586c79ef259SPeter Brune 3587c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3588c79ef259SPeter Brune 3589c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3590c79ef259SPeter Brune @*/ 3591c79ef259SPeter Brune 35924a2ae208SSatish Balay #undef __FUNCT__ 3593646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3594646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3595646217ecSPeter Brune { 35966cab3a1bSJed Brown PetscErrorCode ierr; 35976cab3a1bSJed Brown DM dm; 35986cab3a1bSJed Brown 3599646217ecSPeter Brune PetscFunctionBegin; 3600646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36016cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 36026cab3a1bSJed Brown ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr); 3603646217ecSPeter Brune PetscFunctionReturn(0); 3604646217ecSPeter Brune } 3605646217ecSPeter Brune 36064a2ae208SSatish Balay #undef __FUNCT__ 36074a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 36083c7409f5SSatish Balay /*@C 36093c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3610d850072dSLois Curfman McInnes SNES options in the database. 36113c7409f5SSatish Balay 36123f9fe445SBarry Smith Logically Collective on SNES 3613fee21e36SBarry Smith 3614c7afd0dbSLois Curfman McInnes Input Parameter: 3615c7afd0dbSLois Curfman McInnes + snes - the SNES context 3616c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3617c7afd0dbSLois Curfman McInnes 3618d850072dSLois Curfman McInnes Notes: 3619a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3620c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3621d850072dSLois Curfman McInnes 362236851e7fSLois Curfman McInnes Level: advanced 362336851e7fSLois Curfman McInnes 36243c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3625a86d99e1SLois Curfman McInnes 3626a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 36273c7409f5SSatish Balay @*/ 36287087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 36293c7409f5SSatish Balay { 3630dfbe8321SBarry Smith PetscErrorCode ierr; 36313c7409f5SSatish Balay 36323a40ed3dSBarry Smith PetscFunctionBegin; 36330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3634639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 36351cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 363694b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 36373a40ed3dSBarry Smith PetscFunctionReturn(0); 36383c7409f5SSatish Balay } 36393c7409f5SSatish Balay 36404a2ae208SSatish Balay #undef __FUNCT__ 36414a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 36423c7409f5SSatish Balay /*@C 3643f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3644d850072dSLois Curfman McInnes SNES options in the database. 36453c7409f5SSatish Balay 36463f9fe445SBarry Smith Logically Collective on SNES 3647fee21e36SBarry Smith 3648c7afd0dbSLois Curfman McInnes Input Parameters: 3649c7afd0dbSLois Curfman McInnes + snes - the SNES context 3650c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3651c7afd0dbSLois Curfman McInnes 3652d850072dSLois Curfman McInnes Notes: 3653a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3654c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3655d850072dSLois Curfman McInnes 365636851e7fSLois Curfman McInnes Level: advanced 365736851e7fSLois Curfman McInnes 36583c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3659a86d99e1SLois Curfman McInnes 3660a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 36613c7409f5SSatish Balay @*/ 36627087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 36633c7409f5SSatish Balay { 3664dfbe8321SBarry Smith PetscErrorCode ierr; 36653c7409f5SSatish Balay 36663a40ed3dSBarry Smith PetscFunctionBegin; 36670700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3668639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 36691cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 367094b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 36713a40ed3dSBarry Smith PetscFunctionReturn(0); 36723c7409f5SSatish Balay } 36733c7409f5SSatish Balay 36744a2ae208SSatish Balay #undef __FUNCT__ 36754a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 36769ab63eb5SSatish Balay /*@C 36773c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 36783c7409f5SSatish Balay SNES options in the database. 36793c7409f5SSatish Balay 3680c7afd0dbSLois Curfman McInnes Not Collective 3681c7afd0dbSLois Curfman McInnes 36823c7409f5SSatish Balay Input Parameter: 36833c7409f5SSatish Balay . snes - the SNES context 36843c7409f5SSatish Balay 36853c7409f5SSatish Balay Output Parameter: 36863c7409f5SSatish Balay . prefix - pointer to the prefix string used 36873c7409f5SSatish Balay 36884ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 36899ab63eb5SSatish Balay sufficient length to hold the prefix. 36909ab63eb5SSatish Balay 369136851e7fSLois Curfman McInnes Level: advanced 369236851e7fSLois Curfman McInnes 36933c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 3694a86d99e1SLois Curfman McInnes 3695a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 36963c7409f5SSatish Balay @*/ 36977087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 36983c7409f5SSatish Balay { 3699dfbe8321SBarry Smith PetscErrorCode ierr; 37003c7409f5SSatish Balay 37013a40ed3dSBarry Smith PetscFunctionBegin; 37020700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3703639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 37043a40ed3dSBarry Smith PetscFunctionReturn(0); 37053c7409f5SSatish Balay } 37063c7409f5SSatish Balay 3707b2002411SLois Curfman McInnes 37084a2ae208SSatish Balay #undef __FUNCT__ 37094a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 37103cea93caSBarry Smith /*@C 37113cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 37123cea93caSBarry Smith 37137f6c08e0SMatthew Knepley Level: advanced 37143cea93caSBarry Smith @*/ 37157087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3716b2002411SLois Curfman McInnes { 3717e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3718dfbe8321SBarry Smith PetscErrorCode ierr; 3719b2002411SLois Curfman McInnes 3720b2002411SLois Curfman McInnes PetscFunctionBegin; 3721b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3722c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3723b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3724b2002411SLois Curfman McInnes } 3725da9b6338SBarry Smith 3726da9b6338SBarry Smith #undef __FUNCT__ 3727da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 37287087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3729da9b6338SBarry Smith { 3730dfbe8321SBarry Smith PetscErrorCode ierr; 373177431f27SBarry Smith PetscInt N,i,j; 3732da9b6338SBarry Smith Vec u,uh,fh; 3733da9b6338SBarry Smith PetscScalar value; 3734da9b6338SBarry Smith PetscReal norm; 3735da9b6338SBarry Smith 3736da9b6338SBarry Smith PetscFunctionBegin; 3737da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3738da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3739da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3740da9b6338SBarry Smith 3741da9b6338SBarry Smith /* currently only works for sequential */ 3742da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3743da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3744da9b6338SBarry Smith for (i=0; i<N; i++) { 3745da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 374677431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3747da9b6338SBarry Smith for (j=-10; j<11; j++) { 3748ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3749da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 37503ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3751da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 375277431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3753da9b6338SBarry Smith value = -value; 3754da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3755da9b6338SBarry Smith } 3756da9b6338SBarry Smith } 37576bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 37586bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 3759da9b6338SBarry Smith PetscFunctionReturn(0); 3760da9b6338SBarry Smith } 376171f87433Sdalcinl 376271f87433Sdalcinl #undef __FUNCT__ 3763fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 376471f87433Sdalcinl /*@ 3765fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 376671f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 376771f87433Sdalcinl Newton method. 376871f87433Sdalcinl 37693f9fe445SBarry Smith Logically Collective on SNES 377071f87433Sdalcinl 377171f87433Sdalcinl Input Parameters: 377271f87433Sdalcinl + snes - SNES context 377371f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 377471f87433Sdalcinl 377564ba62caSBarry Smith Options Database: 377664ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 377764ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 377864ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 377964ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 378064ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 378164ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 378264ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 378364ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 378464ba62caSBarry Smith 378571f87433Sdalcinl Notes: 378671f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 378771f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 378871f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 378971f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 379071f87433Sdalcinl solver. 379171f87433Sdalcinl 379271f87433Sdalcinl Level: advanced 379371f87433Sdalcinl 379471f87433Sdalcinl Reference: 379571f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 379671f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 379771f87433Sdalcinl 379871f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 379971f87433Sdalcinl 3800fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 380171f87433Sdalcinl @*/ 38027087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 380371f87433Sdalcinl { 380471f87433Sdalcinl PetscFunctionBegin; 38050700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3806acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 380771f87433Sdalcinl snes->ksp_ewconv = flag; 380871f87433Sdalcinl PetscFunctionReturn(0); 380971f87433Sdalcinl } 381071f87433Sdalcinl 381171f87433Sdalcinl #undef __FUNCT__ 3812fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 381371f87433Sdalcinl /*@ 3814fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 381571f87433Sdalcinl for computing relative tolerance for linear solvers within an 381671f87433Sdalcinl inexact Newton method. 381771f87433Sdalcinl 381871f87433Sdalcinl Not Collective 381971f87433Sdalcinl 382071f87433Sdalcinl Input Parameter: 382171f87433Sdalcinl . snes - SNES context 382271f87433Sdalcinl 382371f87433Sdalcinl Output Parameter: 382471f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 382571f87433Sdalcinl 382671f87433Sdalcinl Notes: 382771f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 382871f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 382971f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 383071f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 383171f87433Sdalcinl solver. 383271f87433Sdalcinl 383371f87433Sdalcinl Level: advanced 383471f87433Sdalcinl 383571f87433Sdalcinl Reference: 383671f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 383771f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 383871f87433Sdalcinl 383971f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 384071f87433Sdalcinl 3841fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 384271f87433Sdalcinl @*/ 38437087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 384471f87433Sdalcinl { 384571f87433Sdalcinl PetscFunctionBegin; 38460700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 384771f87433Sdalcinl PetscValidPointer(flag,2); 384871f87433Sdalcinl *flag = snes->ksp_ewconv; 384971f87433Sdalcinl PetscFunctionReturn(0); 385071f87433Sdalcinl } 385171f87433Sdalcinl 385271f87433Sdalcinl #undef __FUNCT__ 3853fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 385471f87433Sdalcinl /*@ 3855fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 385671f87433Sdalcinl convergence criteria for the linear solvers within an inexact 385771f87433Sdalcinl Newton method. 385871f87433Sdalcinl 38593f9fe445SBarry Smith Logically Collective on SNES 386071f87433Sdalcinl 386171f87433Sdalcinl Input Parameters: 386271f87433Sdalcinl + snes - SNES context 386371f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 386471f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 386571f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 386671f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 386771f87433Sdalcinl (0 <= gamma2 <= 1) 386871f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 386971f87433Sdalcinl . alpha2 - power for safeguard 387071f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 387171f87433Sdalcinl 387271f87433Sdalcinl Note: 387371f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 387471f87433Sdalcinl 387571f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 387671f87433Sdalcinl 387771f87433Sdalcinl Level: advanced 387871f87433Sdalcinl 387971f87433Sdalcinl Reference: 388071f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 388171f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 388271f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 388371f87433Sdalcinl 388471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 388571f87433Sdalcinl 3886fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 388771f87433Sdalcinl @*/ 38887087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 388971f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 389071f87433Sdalcinl { 3891fa9f3622SBarry Smith SNESKSPEW *kctx; 389271f87433Sdalcinl PetscFunctionBegin; 38930700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3894fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3895e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 3896c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 3897c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 3898c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 3899c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 3900c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 3901c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 3902c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 390371f87433Sdalcinl 390471f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 390571f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 390671f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 390771f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 390871f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 390971f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 391071f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 391171f87433Sdalcinl 391271f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 3913e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 391471f87433Sdalcinl } 391571f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 3916e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 391771f87433Sdalcinl } 391871f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 3919e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 392071f87433Sdalcinl } 392171f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 3922e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 392371f87433Sdalcinl } 392471f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 3925e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 392671f87433Sdalcinl } 392771f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 3928e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 392971f87433Sdalcinl } 393071f87433Sdalcinl PetscFunctionReturn(0); 393171f87433Sdalcinl } 393271f87433Sdalcinl 393371f87433Sdalcinl #undef __FUNCT__ 3934fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 393571f87433Sdalcinl /*@ 3936fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 393771f87433Sdalcinl convergence criteria for the linear solvers within an inexact 393871f87433Sdalcinl Newton method. 393971f87433Sdalcinl 394071f87433Sdalcinl Not Collective 394171f87433Sdalcinl 394271f87433Sdalcinl Input Parameters: 394371f87433Sdalcinl snes - SNES context 394471f87433Sdalcinl 394571f87433Sdalcinl Output Parameters: 394671f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 394771f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 394871f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 394971f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 395071f87433Sdalcinl (0 <= gamma2 <= 1) 395171f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 395271f87433Sdalcinl . alpha2 - power for safeguard 395371f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 395471f87433Sdalcinl 395571f87433Sdalcinl Level: advanced 395671f87433Sdalcinl 395771f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 395871f87433Sdalcinl 3959fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 396071f87433Sdalcinl @*/ 39617087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 396271f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 396371f87433Sdalcinl { 3964fa9f3622SBarry Smith SNESKSPEW *kctx; 396571f87433Sdalcinl PetscFunctionBegin; 39660700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3967fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3968e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 396971f87433Sdalcinl if(version) *version = kctx->version; 397071f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 397171f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 397271f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 397371f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 397471f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 397571f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 397671f87433Sdalcinl PetscFunctionReturn(0); 397771f87433Sdalcinl } 397871f87433Sdalcinl 397971f87433Sdalcinl #undef __FUNCT__ 3980fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 3981fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 398271f87433Sdalcinl { 398371f87433Sdalcinl PetscErrorCode ierr; 3984fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 398571f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 398671f87433Sdalcinl 398771f87433Sdalcinl PetscFunctionBegin; 3988e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 398971f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 399071f87433Sdalcinl rtol = kctx->rtol_0; 399171f87433Sdalcinl } else { 399271f87433Sdalcinl if (kctx->version == 1) { 399371f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 399471f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 399571f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 399671f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 399771f87433Sdalcinl } else if (kctx->version == 2) { 399871f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 399971f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 400071f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 400171f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 400271f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 400371f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 400471f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 400571f87433Sdalcinl stol = PetscMax(rtol,stol); 400671f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 400771f87433Sdalcinl /* safeguard: avoid oversolving */ 400871f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 400971f87433Sdalcinl stol = PetscMax(rtol,stol); 401071f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 4011e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 401271f87433Sdalcinl } 401371f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 401471f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 401571f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 401671f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 401771f87433Sdalcinl PetscFunctionReturn(0); 401871f87433Sdalcinl } 401971f87433Sdalcinl 402071f87433Sdalcinl #undef __FUNCT__ 4021fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 4022fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 402371f87433Sdalcinl { 402471f87433Sdalcinl PetscErrorCode ierr; 4025fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 402671f87433Sdalcinl PCSide pcside; 402771f87433Sdalcinl Vec lres; 402871f87433Sdalcinl 402971f87433Sdalcinl PetscFunctionBegin; 4030e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 403171f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 403271f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 403371f87433Sdalcinl if (kctx->version == 1) { 4034b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 403571f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 403671f87433Sdalcinl /* KSP residual is true linear residual */ 403771f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 403871f87433Sdalcinl } else { 403971f87433Sdalcinl /* KSP residual is preconditioned residual */ 404071f87433Sdalcinl /* compute true linear residual norm */ 404171f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 404271f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 404371f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 404471f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 40456bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 404671f87433Sdalcinl } 404771f87433Sdalcinl } 404871f87433Sdalcinl PetscFunctionReturn(0); 404971f87433Sdalcinl } 405071f87433Sdalcinl 405171f87433Sdalcinl #undef __FUNCT__ 405271f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 405371f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 405471f87433Sdalcinl { 405571f87433Sdalcinl PetscErrorCode ierr; 405671f87433Sdalcinl 405771f87433Sdalcinl PetscFunctionBegin; 4058fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 405971f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 4060fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 406171f87433Sdalcinl PetscFunctionReturn(0); 406271f87433Sdalcinl } 40636c699258SBarry Smith 40646c699258SBarry Smith #undef __FUNCT__ 40656c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 40666c699258SBarry Smith /*@ 40676c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 40686c699258SBarry Smith 40693f9fe445SBarry Smith Logically Collective on SNES 40706c699258SBarry Smith 40716c699258SBarry Smith Input Parameters: 40726c699258SBarry Smith + snes - the preconditioner context 40736c699258SBarry Smith - dm - the dm 40746c699258SBarry Smith 40756c699258SBarry Smith Level: intermediate 40766c699258SBarry Smith 40776c699258SBarry Smith 40786c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 40796c699258SBarry Smith @*/ 40807087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 40816c699258SBarry Smith { 40826c699258SBarry Smith PetscErrorCode ierr; 4083345fed2cSBarry Smith KSP ksp; 40846cab3a1bSJed Brown SNESDM sdm; 40856c699258SBarry Smith 40866c699258SBarry Smith PetscFunctionBegin; 40870700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4088d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 40896cab3a1bSJed Brown if (snes->dm) { /* Move the SNESDM context over to the new DM unless the new DM already has one */ 40906cab3a1bSJed Brown PetscContainer oldcontainer,container; 40916cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 40926cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr); 40936cab3a1bSJed Brown if (oldcontainer && !container) { 40946cab3a1bSJed Brown ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr); 40956cab3a1bSJed Brown ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr); 40966cab3a1bSJed Brown if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */ 40976cab3a1bSJed Brown sdm->originaldm = dm; 40986cab3a1bSJed Brown } 40996cab3a1bSJed Brown } 41006bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 41016cab3a1bSJed Brown } 41026c699258SBarry Smith snes->dm = dm; 4103345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4104345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4105f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 41062c155ee1SBarry Smith if (snes->pc) { 41072c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 41082c155ee1SBarry Smith } 41096c699258SBarry Smith PetscFunctionReturn(0); 41106c699258SBarry Smith } 41116c699258SBarry Smith 41126c699258SBarry Smith #undef __FUNCT__ 41136c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 41146c699258SBarry Smith /*@ 41156c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 41166c699258SBarry Smith 41173f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 41186c699258SBarry Smith 41196c699258SBarry Smith Input Parameter: 41206c699258SBarry Smith . snes - the preconditioner context 41216c699258SBarry Smith 41226c699258SBarry Smith Output Parameter: 41236c699258SBarry Smith . dm - the dm 41246c699258SBarry Smith 41256c699258SBarry Smith Level: intermediate 41266c699258SBarry Smith 41276c699258SBarry Smith 41286c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 41296c699258SBarry Smith @*/ 41307087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 41316c699258SBarry Smith { 41326cab3a1bSJed Brown PetscErrorCode ierr; 41336cab3a1bSJed Brown 41346c699258SBarry Smith PetscFunctionBegin; 41350700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 41366cab3a1bSJed Brown if (!snes->dm) { 41376cab3a1bSJed Brown ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr); 41386cab3a1bSJed Brown } 41396c699258SBarry Smith *dm = snes->dm; 41406c699258SBarry Smith PetscFunctionReturn(0); 41416c699258SBarry Smith } 41420807856dSBarry Smith 414331823bd8SMatthew G Knepley #undef __FUNCT__ 414431823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 414531823bd8SMatthew G Knepley /*@ 4146fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 414731823bd8SMatthew G Knepley 414831823bd8SMatthew G Knepley Collective on SNES 414931823bd8SMatthew G Knepley 415031823bd8SMatthew G Knepley Input Parameters: 415131823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 415231823bd8SMatthew G Knepley - pc - the preconditioner object 415331823bd8SMatthew G Knepley 415431823bd8SMatthew G Knepley Notes: 415531823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 415631823bd8SMatthew G Knepley to configure it using the API). 415731823bd8SMatthew G Knepley 415831823bd8SMatthew G Knepley Level: developer 415931823bd8SMatthew G Knepley 416031823bd8SMatthew G Knepley .keywords: SNES, set, precondition 416131823bd8SMatthew G Knepley .seealso: SNESGetPC() 416231823bd8SMatthew G Knepley @*/ 416331823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 416431823bd8SMatthew G Knepley { 416531823bd8SMatthew G Knepley PetscErrorCode ierr; 416631823bd8SMatthew G Knepley 416731823bd8SMatthew G Knepley PetscFunctionBegin; 416831823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 416931823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 417031823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 417131823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4172bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 417331823bd8SMatthew G Knepley snes->pc = pc; 417431823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 417531823bd8SMatthew G Knepley PetscFunctionReturn(0); 417631823bd8SMatthew G Knepley } 417731823bd8SMatthew G Knepley 417831823bd8SMatthew G Knepley #undef __FUNCT__ 417931823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 418031823bd8SMatthew G Knepley /*@ 4181fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 418231823bd8SMatthew G Knepley 418331823bd8SMatthew G Knepley Not Collective 418431823bd8SMatthew G Knepley 418531823bd8SMatthew G Knepley Input Parameter: 418631823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 418731823bd8SMatthew G Knepley 418831823bd8SMatthew G Knepley Output Parameter: 418931823bd8SMatthew G Knepley . pc - preconditioner context 419031823bd8SMatthew G Knepley 419131823bd8SMatthew G Knepley Level: developer 419231823bd8SMatthew G Knepley 419331823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 419431823bd8SMatthew G Knepley .seealso: SNESSetPC() 419531823bd8SMatthew G Knepley @*/ 419631823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 419731823bd8SMatthew G Knepley { 419831823bd8SMatthew G Knepley PetscErrorCode ierr; 419931823bd8SMatthew G Knepley 420031823bd8SMatthew G Knepley PetscFunctionBegin; 420131823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 420231823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 420331823bd8SMatthew G Knepley if (!snes->pc) { 420431823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr); 42054a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr); 420631823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 420731823bd8SMatthew G Knepley } 420831823bd8SMatthew G Knepley *pc = snes->pc; 420931823bd8SMatthew G Knepley PetscFunctionReturn(0); 421031823bd8SMatthew G Knepley } 421131823bd8SMatthew G Knepley 42129e764e56SPeter Brune #undef __FUNCT__ 42139e764e56SPeter Brune #define __FUNCT__ "SNESSetPetscLineSearch" 42149e764e56SPeter Brune /*@ 42159e764e56SPeter Brune SNESSetPetscLineSearch - Sets the linesearch. 42169e764e56SPeter Brune 42179e764e56SPeter Brune Collective on SNES 42189e764e56SPeter Brune 42199e764e56SPeter Brune Input Parameters: 42209e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 42219e764e56SPeter Brune - linesearch - the linesearch object 42229e764e56SPeter Brune 42239e764e56SPeter Brune Notes: 42249e764e56SPeter Brune Use SNESGetPetscLineSearch() to retrieve the preconditioner context (for example, 42259e764e56SPeter Brune to configure it using the API). 42269e764e56SPeter Brune 42279e764e56SPeter Brune Level: developer 42289e764e56SPeter Brune 42299e764e56SPeter Brune .keywords: SNES, set, linesearch 4230ea5d4fccSPeter Brune .seealso: SNESGetPetscLineSearch() 42319e764e56SPeter Brune @*/ 42329e764e56SPeter Brune PetscErrorCode SNESSetPetscLineSearch(SNES snes, PetscLineSearch linesearch) 42339e764e56SPeter Brune { 42349e764e56SPeter Brune PetscErrorCode ierr; 42359e764e56SPeter Brune 42369e764e56SPeter Brune PetscFunctionBegin; 42379e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 42389e764e56SPeter Brune PetscValidHeaderSpecific(linesearch, PETSCLINESEARCH_CLASSID, 2); 42399e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 42409e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 42419e764e56SPeter Brune ierr = PetscLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 42429e764e56SPeter Brune snes->linesearch = linesearch; 42439e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 42449e764e56SPeter Brune PetscFunctionReturn(0); 42459e764e56SPeter Brune } 42469e764e56SPeter Brune 42479e764e56SPeter Brune #undef __FUNCT__ 42489e764e56SPeter Brune #define __FUNCT__ "SNESGetPetscLineSearch" 4249ea5d4fccSPeter Brune /*@C 42509e764e56SPeter Brune SNESGetPetscLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch(). 42519e764e56SPeter Brune 42529e764e56SPeter Brune Not Collective 42539e764e56SPeter Brune 42549e764e56SPeter Brune Input Parameter: 42559e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 42569e764e56SPeter Brune 42579e764e56SPeter Brune Output Parameter: 42589e764e56SPeter Brune . linesearch - linesearch context 42599e764e56SPeter Brune 42609e764e56SPeter Brune Level: developer 42619e764e56SPeter Brune 42629e764e56SPeter Brune .keywords: SNES, get, linesearch 42639e764e56SPeter Brune .seealso: SNESSetPetscLineSearch() 42649e764e56SPeter Brune @*/ 42659e764e56SPeter Brune PetscErrorCode SNESGetPetscLineSearch(SNES snes, PetscLineSearch *linesearch) 42669e764e56SPeter Brune { 42679e764e56SPeter Brune PetscErrorCode ierr; 42689e764e56SPeter Brune const char *optionsprefix; 42699e764e56SPeter Brune 42709e764e56SPeter Brune PetscFunctionBegin; 42719e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 42729e764e56SPeter Brune PetscValidPointer(linesearch, 2); 42739e764e56SPeter Brune if (!snes->linesearch) { 42749e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 42759e764e56SPeter Brune ierr = PetscLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr); 42769e764e56SPeter Brune ierr = PetscLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 42779e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 42789e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 42799e764e56SPeter Brune } 42809e764e56SPeter Brune *linesearch = snes->linesearch; 42819e764e56SPeter Brune PetscFunctionReturn(0); 42829e764e56SPeter Brune } 42839e764e56SPeter Brune 428469b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4285c6db04a5SJed Brown #include <mex.h> 428669b4f73cSBarry Smith 42878f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 42888f6e6473SBarry Smith 42890807856dSBarry Smith #undef __FUNCT__ 42900807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 42910807856dSBarry Smith /* 42920807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 42930807856dSBarry Smith SNESSetFunctionMatlab(). 42940807856dSBarry Smith 42950807856dSBarry Smith Collective on SNES 42960807856dSBarry Smith 42970807856dSBarry Smith Input Parameters: 42980807856dSBarry Smith + snes - the SNES context 42990807856dSBarry Smith - x - input vector 43000807856dSBarry Smith 43010807856dSBarry Smith Output Parameter: 43020807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 43030807856dSBarry Smith 43040807856dSBarry Smith Notes: 43050807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 43060807856dSBarry Smith implementations, so most users would not generally call this routine 43070807856dSBarry Smith themselves. 43080807856dSBarry Smith 43090807856dSBarry Smith Level: developer 43100807856dSBarry Smith 43110807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 43120807856dSBarry Smith 43130807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 431461b2408cSBarry Smith */ 43157087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 43160807856dSBarry Smith { 4317e650e774SBarry Smith PetscErrorCode ierr; 43188f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 43198f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 43208f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 432191621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 4322e650e774SBarry Smith 43230807856dSBarry Smith PetscFunctionBegin; 43240807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 43250807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 43260807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 43270807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 43280807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 43290807856dSBarry Smith 43300807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 4331e650e774SBarry Smith 433291621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4333e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4334e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 433591621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 433691621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 433791621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 43388f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 43398f6e6473SBarry Smith prhs[4] = sctx->ctx; 4340b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 4341e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4342e650e774SBarry Smith mxDestroyArray(prhs[0]); 4343e650e774SBarry Smith mxDestroyArray(prhs[1]); 4344e650e774SBarry Smith mxDestroyArray(prhs[2]); 43458f6e6473SBarry Smith mxDestroyArray(prhs[3]); 4346e650e774SBarry Smith mxDestroyArray(plhs[0]); 43470807856dSBarry Smith PetscFunctionReturn(0); 43480807856dSBarry Smith } 43490807856dSBarry Smith 43500807856dSBarry Smith 43510807856dSBarry Smith #undef __FUNCT__ 43520807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 435361b2408cSBarry Smith /* 43540807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 43550807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4356e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 43570807856dSBarry Smith 43580807856dSBarry Smith Logically Collective on SNES 43590807856dSBarry Smith 43600807856dSBarry Smith Input Parameters: 43610807856dSBarry Smith + snes - the SNES context 43620807856dSBarry Smith . r - vector to store function value 43630807856dSBarry Smith - func - function evaluation routine 43640807856dSBarry Smith 43650807856dSBarry Smith Calling sequence of func: 436661b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 43670807856dSBarry Smith 43680807856dSBarry Smith 43690807856dSBarry Smith Notes: 43700807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 43710807856dSBarry Smith $ f'(x) x = -f(x), 43720807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 43730807856dSBarry Smith 43740807856dSBarry Smith Level: beginner 43750807856dSBarry Smith 43760807856dSBarry Smith .keywords: SNES, nonlinear, set, function 43770807856dSBarry Smith 43780807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 437961b2408cSBarry Smith */ 43807087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 43810807856dSBarry Smith { 43820807856dSBarry Smith PetscErrorCode ierr; 43838f6e6473SBarry Smith SNESMatlabContext *sctx; 43840807856dSBarry Smith 43850807856dSBarry Smith PetscFunctionBegin; 43868f6e6473SBarry Smith /* currently sctx is memory bleed */ 43878f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 43888f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 43898f6e6473SBarry Smith /* 43908f6e6473SBarry Smith This should work, but it doesn't 43918f6e6473SBarry Smith sctx->ctx = ctx; 43928f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 43938f6e6473SBarry Smith */ 43948f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 43958f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 43960807856dSBarry Smith PetscFunctionReturn(0); 43970807856dSBarry Smith } 439869b4f73cSBarry Smith 439961b2408cSBarry Smith #undef __FUNCT__ 440061b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 440161b2408cSBarry Smith /* 440261b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 440361b2408cSBarry Smith SNESSetJacobianMatlab(). 440461b2408cSBarry Smith 440561b2408cSBarry Smith Collective on SNES 440661b2408cSBarry Smith 440761b2408cSBarry Smith Input Parameters: 440861b2408cSBarry Smith + snes - the SNES context 440961b2408cSBarry Smith . x - input vector 441061b2408cSBarry Smith . A, B - the matrices 441161b2408cSBarry Smith - ctx - user context 441261b2408cSBarry Smith 441361b2408cSBarry Smith Output Parameter: 441461b2408cSBarry Smith . flag - structure of the matrix 441561b2408cSBarry Smith 441661b2408cSBarry Smith Level: developer 441761b2408cSBarry Smith 441861b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 441961b2408cSBarry Smith 442061b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 442161b2408cSBarry Smith @*/ 44227087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 442361b2408cSBarry Smith { 442461b2408cSBarry Smith PetscErrorCode ierr; 442561b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 442661b2408cSBarry Smith int nlhs = 2,nrhs = 6; 442761b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 442861b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 442961b2408cSBarry Smith 443061b2408cSBarry Smith PetscFunctionBegin; 443161b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 443261b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 443361b2408cSBarry Smith 443461b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 443561b2408cSBarry Smith 443661b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 443761b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 443861b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 443961b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 444061b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 444161b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 444261b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 444361b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 444461b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 444561b2408cSBarry Smith prhs[5] = sctx->ctx; 4446b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 444761b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 444861b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 444961b2408cSBarry Smith mxDestroyArray(prhs[0]); 445061b2408cSBarry Smith mxDestroyArray(prhs[1]); 445161b2408cSBarry Smith mxDestroyArray(prhs[2]); 445261b2408cSBarry Smith mxDestroyArray(prhs[3]); 445361b2408cSBarry Smith mxDestroyArray(prhs[4]); 445461b2408cSBarry Smith mxDestroyArray(plhs[0]); 445561b2408cSBarry Smith mxDestroyArray(plhs[1]); 445661b2408cSBarry Smith PetscFunctionReturn(0); 445761b2408cSBarry Smith } 445861b2408cSBarry Smith 445961b2408cSBarry Smith 446061b2408cSBarry Smith #undef __FUNCT__ 446161b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 446261b2408cSBarry Smith /* 446361b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 446461b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4465e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 446661b2408cSBarry Smith 446761b2408cSBarry Smith Logically Collective on SNES 446861b2408cSBarry Smith 446961b2408cSBarry Smith Input Parameters: 447061b2408cSBarry Smith + snes - the SNES context 447161b2408cSBarry Smith . A,B - Jacobian matrices 447261b2408cSBarry Smith . func - function evaluation routine 447361b2408cSBarry Smith - ctx - user context 447461b2408cSBarry Smith 447561b2408cSBarry Smith Calling sequence of func: 447661b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 447761b2408cSBarry Smith 447861b2408cSBarry Smith 447961b2408cSBarry Smith Level: developer 448061b2408cSBarry Smith 448161b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 448261b2408cSBarry Smith 448361b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 448461b2408cSBarry Smith */ 44857087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 448661b2408cSBarry Smith { 448761b2408cSBarry Smith PetscErrorCode ierr; 448861b2408cSBarry Smith SNESMatlabContext *sctx; 448961b2408cSBarry Smith 449061b2408cSBarry Smith PetscFunctionBegin; 449161b2408cSBarry Smith /* currently sctx is memory bleed */ 449261b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 449361b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 449461b2408cSBarry Smith /* 449561b2408cSBarry Smith This should work, but it doesn't 449661b2408cSBarry Smith sctx->ctx = ctx; 449761b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 449861b2408cSBarry Smith */ 449961b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 450061b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 450161b2408cSBarry Smith PetscFunctionReturn(0); 450261b2408cSBarry Smith } 450369b4f73cSBarry Smith 4504f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4505f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4506f9eb7ae2SShri Abhyankar /* 4507f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4508f9eb7ae2SShri Abhyankar 4509f9eb7ae2SShri Abhyankar Collective on SNES 4510f9eb7ae2SShri Abhyankar 4511f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4512f9eb7ae2SShri Abhyankar @*/ 45137087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4514f9eb7ae2SShri Abhyankar { 4515f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 451648f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4517f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4518f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4519f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4520f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4521f9eb7ae2SShri Abhyankar 4522f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4523f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4524f9eb7ae2SShri Abhyankar 4525f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4526f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4527f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4528f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4529f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4530f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4531f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4532f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4533f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4534f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4535f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4536f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4537f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4538f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4539f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4540f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4541f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4542f9eb7ae2SShri Abhyankar } 4543f9eb7ae2SShri Abhyankar 4544f9eb7ae2SShri Abhyankar 4545f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4546f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4547f9eb7ae2SShri Abhyankar /* 4548e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4549f9eb7ae2SShri Abhyankar 4550f9eb7ae2SShri Abhyankar Level: developer 4551f9eb7ae2SShri Abhyankar 4552f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4553f9eb7ae2SShri Abhyankar 4554f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4555f9eb7ae2SShri Abhyankar */ 45567087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4557f9eb7ae2SShri Abhyankar { 4558f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4559f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4560f9eb7ae2SShri Abhyankar 4561f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4562f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4563f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4564f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4565f9eb7ae2SShri Abhyankar /* 4566f9eb7ae2SShri Abhyankar This should work, but it doesn't 4567f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4568f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4569f9eb7ae2SShri Abhyankar */ 4570f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4571f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4572f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4573f9eb7ae2SShri Abhyankar } 4574f9eb7ae2SShri Abhyankar 457569b4f73cSBarry Smith #endif 4576