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 { 458*872b6db9SPeter Brune PetscBool flg,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 60176b2cf59SMatthew Knepley for(i = 0; i < numberofsetfromoptions; i++) { 60276b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 60376b2cf59SMatthew Knepley } 60476b2cf59SMatthew Knepley 605e7788613SBarry Smith if (snes->ops->setfromoptions) { 606e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 607639f9d9dSBarry Smith } 6085d973c19SBarry Smith 6095d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 6105d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 611b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 6124bbc92c1SBarry Smith 613aa3661deSLisandro Dalcin if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 6141cee3971SBarry Smith 6151cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 616aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 617aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 61885385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 61993993e2dSLois Curfman McInnes 6209e764e56SPeter Brune if (!snes->linesearch) { 6219e764e56SPeter Brune ierr = SNESGetPetscLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 6229e764e56SPeter Brune } 6239e764e56SPeter Brune ierr = PetscLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr); 6249e764e56SPeter Brune 62551e86f29SPeter Brune /* if someone has set the SNES PC type, create it. */ 62651e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 62751e86f29SPeter Brune ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 62851e86f29SPeter Brune if (pcset && (!snes->pc)) { 62951e86f29SPeter Brune ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr); 63051e86f29SPeter Brune } 6314a0c5b0cSMatthew G Knepley if (snes->pc) { 632fde0ff24SPeter Brune ierr = SNESSetOptionsPrefix(snes->pc, optionsprefix);CHKERRQ(ierr); 633fde0ff24SPeter Brune ierr = SNESAppendOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr); 6344a0c5b0cSMatthew G Knepley ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 6354a0c5b0cSMatthew G Knepley ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 6364a0c5b0cSMatthew G Knepley } 6373a40ed3dSBarry Smith PetscFunctionReturn(0); 6389b94acceSBarry Smith } 6399b94acceSBarry Smith 640d25893d9SBarry Smith #undef __FUNCT__ 641d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 642d25893d9SBarry Smith /*@ 643d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 644d25893d9SBarry Smith the nonlinear solvers. 645d25893d9SBarry Smith 646d25893d9SBarry Smith Logically Collective on SNES 647d25893d9SBarry Smith 648d25893d9SBarry Smith Input Parameters: 649d25893d9SBarry Smith + snes - the SNES context 650d25893d9SBarry Smith . compute - function to compute the context 651d25893d9SBarry Smith - destroy - function to destroy the context 652d25893d9SBarry Smith 653d25893d9SBarry Smith Level: intermediate 654d25893d9SBarry Smith 655d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 656d25893d9SBarry Smith 657d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 658d25893d9SBarry Smith @*/ 659d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 660d25893d9SBarry Smith { 661d25893d9SBarry Smith PetscFunctionBegin; 662d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 663d25893d9SBarry Smith snes->ops->usercompute = compute; 664d25893d9SBarry Smith snes->ops->userdestroy = destroy; 665d25893d9SBarry Smith PetscFunctionReturn(0); 666d25893d9SBarry Smith } 667a847f771SSatish Balay 6684a2ae208SSatish Balay #undef __FUNCT__ 6694a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 670b07ff414SBarry Smith /*@ 6719b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 6729b94acceSBarry Smith the nonlinear solvers. 6739b94acceSBarry Smith 6743f9fe445SBarry Smith Logically Collective on SNES 675fee21e36SBarry Smith 676c7afd0dbSLois Curfman McInnes Input Parameters: 677c7afd0dbSLois Curfman McInnes + snes - the SNES context 678c7afd0dbSLois Curfman McInnes - usrP - optional user context 679c7afd0dbSLois Curfman McInnes 68036851e7fSLois Curfman McInnes Level: intermediate 68136851e7fSLois Curfman McInnes 6829b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 6839b94acceSBarry Smith 684d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext() 6859b94acceSBarry Smith @*/ 6867087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 6879b94acceSBarry Smith { 6881b2093e4SBarry Smith PetscErrorCode ierr; 689b07ff414SBarry Smith KSP ksp; 6901b2093e4SBarry Smith 6913a40ed3dSBarry Smith PetscFunctionBegin; 6920700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 693b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 694b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 6959b94acceSBarry Smith snes->user = usrP; 6963a40ed3dSBarry Smith PetscFunctionReturn(0); 6979b94acceSBarry Smith } 69874679c65SBarry Smith 6994a2ae208SSatish Balay #undef __FUNCT__ 7004a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 701b07ff414SBarry Smith /*@ 7029b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 7039b94acceSBarry Smith nonlinear solvers. 7049b94acceSBarry Smith 705c7afd0dbSLois Curfman McInnes Not Collective 706c7afd0dbSLois Curfman McInnes 7079b94acceSBarry Smith Input Parameter: 7089b94acceSBarry Smith . snes - SNES context 7099b94acceSBarry Smith 7109b94acceSBarry Smith Output Parameter: 7119b94acceSBarry Smith . usrP - user context 7129b94acceSBarry Smith 71336851e7fSLois Curfman McInnes Level: intermediate 71436851e7fSLois Curfman McInnes 7159b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 7169b94acceSBarry Smith 7179b94acceSBarry Smith .seealso: SNESSetApplicationContext() 7189b94acceSBarry Smith @*/ 719e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 7209b94acceSBarry Smith { 7213a40ed3dSBarry Smith PetscFunctionBegin; 7220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 723e71120c6SJed Brown *(void**)usrP = snes->user; 7243a40ed3dSBarry Smith PetscFunctionReturn(0); 7259b94acceSBarry Smith } 72674679c65SBarry Smith 7274a2ae208SSatish Balay #undef __FUNCT__ 7284a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 7299b94acceSBarry Smith /*@ 730c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 731c8228a4eSBarry Smith at this time. 7329b94acceSBarry Smith 733c7afd0dbSLois Curfman McInnes Not Collective 734c7afd0dbSLois Curfman McInnes 7359b94acceSBarry Smith Input Parameter: 7369b94acceSBarry Smith . snes - SNES context 7379b94acceSBarry Smith 7389b94acceSBarry Smith Output Parameter: 7399b94acceSBarry Smith . iter - iteration number 7409b94acceSBarry Smith 741c8228a4eSBarry Smith Notes: 742c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 743c8228a4eSBarry Smith 744c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 74508405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 74608405cd6SLois Curfman McInnes .vb 74708405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 74808405cd6SLois Curfman McInnes if (!(it % 2)) { 74908405cd6SLois Curfman McInnes [compute Jacobian here] 75008405cd6SLois Curfman McInnes } 75108405cd6SLois Curfman McInnes .ve 752c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 75308405cd6SLois Curfman McInnes recomputed every second SNES iteration. 754c8228a4eSBarry Smith 75536851e7fSLois Curfman McInnes Level: intermediate 75636851e7fSLois Curfman McInnes 7572b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 7582b668275SBarry Smith 759b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 7609b94acceSBarry Smith @*/ 7617087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 7629b94acceSBarry Smith { 7633a40ed3dSBarry Smith PetscFunctionBegin; 7640700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7654482741eSBarry Smith PetscValidIntPointer(iter,2); 7669b94acceSBarry Smith *iter = snes->iter; 7673a40ed3dSBarry Smith PetscFunctionReturn(0); 7689b94acceSBarry Smith } 76974679c65SBarry Smith 7704a2ae208SSatish Balay #undef __FUNCT__ 771360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber" 772360c497dSPeter Brune /*@ 773360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 774360c497dSPeter Brune 775360c497dSPeter Brune Not Collective 776360c497dSPeter Brune 777360c497dSPeter Brune Input Parameter: 778360c497dSPeter Brune . snes - SNES context 779360c497dSPeter Brune . iter - iteration number 780360c497dSPeter Brune 781360c497dSPeter Brune Level: developer 782360c497dSPeter Brune 783360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number, 784360c497dSPeter Brune 785360c497dSPeter Brune .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 786360c497dSPeter Brune @*/ 787360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 788360c497dSPeter Brune { 789360c497dSPeter Brune PetscErrorCode ierr; 790360c497dSPeter Brune 791360c497dSPeter Brune PetscFunctionBegin; 792360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 793360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 794360c497dSPeter Brune snes->iter = iter; 795360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 796360c497dSPeter Brune PetscFunctionReturn(0); 797360c497dSPeter Brune } 798360c497dSPeter Brune 799360c497dSPeter Brune #undef __FUNCT__ 8004a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 8019b94acceSBarry Smith /*@ 8029b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 8039b94acceSBarry Smith with SNESSSetFunction(). 8049b94acceSBarry Smith 805c7afd0dbSLois Curfman McInnes Collective on SNES 806c7afd0dbSLois Curfman McInnes 8079b94acceSBarry Smith Input Parameter: 8089b94acceSBarry Smith . snes - SNES context 8099b94acceSBarry Smith 8109b94acceSBarry Smith Output Parameter: 8119b94acceSBarry Smith . fnorm - 2-norm of function 8129b94acceSBarry Smith 81336851e7fSLois Curfman McInnes Level: intermediate 81436851e7fSLois Curfman McInnes 8159b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 816a86d99e1SLois Curfman McInnes 817b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 8189b94acceSBarry Smith @*/ 8197087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 8209b94acceSBarry Smith { 8213a40ed3dSBarry Smith PetscFunctionBegin; 8220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8234482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 8249b94acceSBarry Smith *fnorm = snes->norm; 8253a40ed3dSBarry Smith PetscFunctionReturn(0); 8269b94acceSBarry Smith } 82774679c65SBarry Smith 828360c497dSPeter Brune 829360c497dSPeter Brune #undef __FUNCT__ 830360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm" 831360c497dSPeter Brune /*@ 832360c497dSPeter Brune SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm(). 833360c497dSPeter Brune 834360c497dSPeter Brune Collective on SNES 835360c497dSPeter Brune 836360c497dSPeter Brune Input Parameter: 837360c497dSPeter Brune . snes - SNES context 838360c497dSPeter Brune . fnorm - 2-norm of function 839360c497dSPeter Brune 840360c497dSPeter Brune Level: developer 841360c497dSPeter Brune 842360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm 843360c497dSPeter Brune 844360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm(). 845360c497dSPeter Brune @*/ 846360c497dSPeter Brune PetscErrorCode SNESSetFunctionNorm(SNES snes,PetscReal fnorm) 847360c497dSPeter Brune { 848360c497dSPeter Brune 849360c497dSPeter Brune PetscErrorCode ierr; 850360c497dSPeter Brune 851360c497dSPeter Brune PetscFunctionBegin; 852360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 853360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 854360c497dSPeter Brune snes->norm = fnorm; 855360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 856360c497dSPeter Brune PetscFunctionReturn(0); 857360c497dSPeter Brune } 858360c497dSPeter Brune 8594a2ae208SSatish Balay #undef __FUNCT__ 860b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 8619b94acceSBarry Smith /*@ 862b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 8639b94acceSBarry Smith attempted by the nonlinear solver. 8649b94acceSBarry Smith 865c7afd0dbSLois Curfman McInnes Not Collective 866c7afd0dbSLois Curfman McInnes 8679b94acceSBarry Smith Input Parameter: 8689b94acceSBarry Smith . snes - SNES context 8699b94acceSBarry Smith 8709b94acceSBarry Smith Output Parameter: 8719b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 8729b94acceSBarry Smith 873c96a6f78SLois Curfman McInnes Notes: 874c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 875c96a6f78SLois Curfman McInnes 87636851e7fSLois Curfman McInnes Level: intermediate 87736851e7fSLois Curfman McInnes 8789b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 87958ebbce7SBarry Smith 880e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 88158ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 8829b94acceSBarry Smith @*/ 8837087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 8849b94acceSBarry Smith { 8853a40ed3dSBarry Smith PetscFunctionBegin; 8860700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8874482741eSBarry Smith PetscValidIntPointer(nfails,2); 88850ffb88aSMatthew Knepley *nfails = snes->numFailures; 88950ffb88aSMatthew Knepley PetscFunctionReturn(0); 89050ffb88aSMatthew Knepley } 89150ffb88aSMatthew Knepley 89250ffb88aSMatthew Knepley #undef __FUNCT__ 893b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 89450ffb88aSMatthew Knepley /*@ 895b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 89650ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 89750ffb88aSMatthew Knepley 89850ffb88aSMatthew Knepley Not Collective 89950ffb88aSMatthew Knepley 90050ffb88aSMatthew Knepley Input Parameters: 90150ffb88aSMatthew Knepley + snes - SNES context 90250ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 90350ffb88aSMatthew Knepley 90450ffb88aSMatthew Knepley Level: intermediate 90550ffb88aSMatthew Knepley 90650ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 90758ebbce7SBarry Smith 908e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 90958ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 91050ffb88aSMatthew Knepley @*/ 9117087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 91250ffb88aSMatthew Knepley { 91350ffb88aSMatthew Knepley PetscFunctionBegin; 9140700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 91550ffb88aSMatthew Knepley snes->maxFailures = maxFails; 91650ffb88aSMatthew Knepley PetscFunctionReturn(0); 91750ffb88aSMatthew Knepley } 91850ffb88aSMatthew Knepley 91950ffb88aSMatthew Knepley #undef __FUNCT__ 920b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 92150ffb88aSMatthew Knepley /*@ 922b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 92350ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 92450ffb88aSMatthew Knepley 92550ffb88aSMatthew Knepley Not Collective 92650ffb88aSMatthew Knepley 92750ffb88aSMatthew Knepley Input Parameter: 92850ffb88aSMatthew Knepley . snes - SNES context 92950ffb88aSMatthew Knepley 93050ffb88aSMatthew Knepley Output Parameter: 93150ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 93250ffb88aSMatthew Knepley 93350ffb88aSMatthew Knepley Level: intermediate 93450ffb88aSMatthew Knepley 93550ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 93658ebbce7SBarry Smith 937e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 93858ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 93958ebbce7SBarry Smith 94050ffb88aSMatthew Knepley @*/ 9417087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 94250ffb88aSMatthew Knepley { 94350ffb88aSMatthew Knepley PetscFunctionBegin; 9440700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9454482741eSBarry Smith PetscValidIntPointer(maxFails,2); 94650ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 9473a40ed3dSBarry Smith PetscFunctionReturn(0); 9489b94acceSBarry Smith } 949a847f771SSatish Balay 9504a2ae208SSatish Balay #undef __FUNCT__ 9512541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 9522541af92SBarry Smith /*@ 9532541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 9542541af92SBarry Smith done by SNES. 9552541af92SBarry Smith 9562541af92SBarry Smith Not Collective 9572541af92SBarry Smith 9582541af92SBarry Smith Input Parameter: 9592541af92SBarry Smith . snes - SNES context 9602541af92SBarry Smith 9612541af92SBarry Smith Output Parameter: 9622541af92SBarry Smith . nfuncs - number of evaluations 9632541af92SBarry Smith 9642541af92SBarry Smith Level: intermediate 9652541af92SBarry Smith 9662541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 96758ebbce7SBarry Smith 968e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 9692541af92SBarry Smith @*/ 9707087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 9712541af92SBarry Smith { 9722541af92SBarry Smith PetscFunctionBegin; 9730700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9742541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 9752541af92SBarry Smith *nfuncs = snes->nfuncs; 9762541af92SBarry Smith PetscFunctionReturn(0); 9772541af92SBarry Smith } 9782541af92SBarry Smith 9792541af92SBarry Smith #undef __FUNCT__ 9803d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 9813d4c4710SBarry Smith /*@ 9823d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 9833d4c4710SBarry Smith linear solvers. 9843d4c4710SBarry Smith 9853d4c4710SBarry Smith Not Collective 9863d4c4710SBarry Smith 9873d4c4710SBarry Smith Input Parameter: 9883d4c4710SBarry Smith . snes - SNES context 9893d4c4710SBarry Smith 9903d4c4710SBarry Smith Output Parameter: 9913d4c4710SBarry Smith . nfails - number of failed solves 9923d4c4710SBarry Smith 9933d4c4710SBarry Smith Notes: 9943d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 9953d4c4710SBarry Smith 9963d4c4710SBarry Smith Level: intermediate 9973d4c4710SBarry Smith 9983d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 99958ebbce7SBarry Smith 1000e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 10013d4c4710SBarry Smith @*/ 10027087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 10033d4c4710SBarry Smith { 10043d4c4710SBarry Smith PetscFunctionBegin; 10050700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10063d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 10073d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 10083d4c4710SBarry Smith PetscFunctionReturn(0); 10093d4c4710SBarry Smith } 10103d4c4710SBarry Smith 10113d4c4710SBarry Smith #undef __FUNCT__ 10123d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 10133d4c4710SBarry Smith /*@ 10143d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 10153d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 10163d4c4710SBarry Smith 10173f9fe445SBarry Smith Logically Collective on SNES 10183d4c4710SBarry Smith 10193d4c4710SBarry Smith Input Parameters: 10203d4c4710SBarry Smith + snes - SNES context 10213d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 10223d4c4710SBarry Smith 10233d4c4710SBarry Smith Level: intermediate 10243d4c4710SBarry Smith 1025a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 10263d4c4710SBarry Smith 10273d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 10283d4c4710SBarry Smith 102958ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 10303d4c4710SBarry Smith @*/ 10317087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 10323d4c4710SBarry Smith { 10333d4c4710SBarry Smith PetscFunctionBegin; 10340700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1035c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 10363d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 10373d4c4710SBarry Smith PetscFunctionReturn(0); 10383d4c4710SBarry Smith } 10393d4c4710SBarry Smith 10403d4c4710SBarry Smith #undef __FUNCT__ 10413d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 10423d4c4710SBarry Smith /*@ 10433d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 10443d4c4710SBarry Smith are allowed before SNES terminates 10453d4c4710SBarry Smith 10463d4c4710SBarry Smith Not Collective 10473d4c4710SBarry Smith 10483d4c4710SBarry Smith Input Parameter: 10493d4c4710SBarry Smith . snes - SNES context 10503d4c4710SBarry Smith 10513d4c4710SBarry Smith Output Parameter: 10523d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 10533d4c4710SBarry Smith 10543d4c4710SBarry Smith Level: intermediate 10553d4c4710SBarry Smith 10563d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 10573d4c4710SBarry Smith 10583d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 10593d4c4710SBarry Smith 1060e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 10613d4c4710SBarry Smith @*/ 10627087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 10633d4c4710SBarry Smith { 10643d4c4710SBarry Smith PetscFunctionBegin; 10650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10663d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 10673d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 10683d4c4710SBarry Smith PetscFunctionReturn(0); 10693d4c4710SBarry Smith } 10703d4c4710SBarry Smith 10713d4c4710SBarry Smith #undef __FUNCT__ 1072b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 1073c96a6f78SLois Curfman McInnes /*@ 1074b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1075c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1076c96a6f78SLois Curfman McInnes 1077c7afd0dbSLois Curfman McInnes Not Collective 1078c7afd0dbSLois Curfman McInnes 1079c96a6f78SLois Curfman McInnes Input Parameter: 1080c96a6f78SLois Curfman McInnes . snes - SNES context 1081c96a6f78SLois Curfman McInnes 1082c96a6f78SLois Curfman McInnes Output Parameter: 1083c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1084c96a6f78SLois Curfman McInnes 1085c96a6f78SLois Curfman McInnes Notes: 1086c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1087c96a6f78SLois Curfman McInnes 108836851e7fSLois Curfman McInnes Level: intermediate 108936851e7fSLois Curfman McInnes 1090c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 10912b668275SBarry Smith 10928c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 1093c96a6f78SLois Curfman McInnes @*/ 10947087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 1095c96a6f78SLois Curfman McInnes { 10963a40ed3dSBarry Smith PetscFunctionBegin; 10970700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10984482741eSBarry Smith PetscValidIntPointer(lits,2); 1099c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 11003a40ed3dSBarry Smith PetscFunctionReturn(0); 1101c96a6f78SLois Curfman McInnes } 1102c96a6f78SLois Curfman McInnes 11034a2ae208SSatish Balay #undef __FUNCT__ 110494b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 110552baeb72SSatish Balay /*@ 110694b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 11079b94acceSBarry Smith 110894b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 1109c7afd0dbSLois Curfman McInnes 11109b94acceSBarry Smith Input Parameter: 11119b94acceSBarry Smith . snes - the SNES context 11129b94acceSBarry Smith 11139b94acceSBarry Smith Output Parameter: 111494b7f48cSBarry Smith . ksp - the KSP context 11159b94acceSBarry Smith 11169b94acceSBarry Smith Notes: 111794b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 11189b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 11192999313aSBarry Smith PC contexts as well. 11209b94acceSBarry Smith 112136851e7fSLois Curfman McInnes Level: beginner 112236851e7fSLois Curfman McInnes 112394b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 11249b94acceSBarry Smith 11252999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 11269b94acceSBarry Smith @*/ 11277087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 11289b94acceSBarry Smith { 11291cee3971SBarry Smith PetscErrorCode ierr; 11301cee3971SBarry Smith 11313a40ed3dSBarry Smith PetscFunctionBegin; 11320700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11334482741eSBarry Smith PetscValidPointer(ksp,2); 11341cee3971SBarry Smith 11351cee3971SBarry Smith if (!snes->ksp) { 11361cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 11371cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 11381cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 11391cee3971SBarry Smith } 114094b7f48cSBarry Smith *ksp = snes->ksp; 11413a40ed3dSBarry Smith PetscFunctionReturn(0); 11429b94acceSBarry Smith } 114382bf6240SBarry Smith 11444a2ae208SSatish Balay #undef __FUNCT__ 11452999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 11462999313aSBarry Smith /*@ 11472999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 11482999313aSBarry Smith 11492999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 11502999313aSBarry Smith 11512999313aSBarry Smith Input Parameters: 11522999313aSBarry Smith + snes - the SNES context 11532999313aSBarry Smith - ksp - the KSP context 11542999313aSBarry Smith 11552999313aSBarry Smith Notes: 11562999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 11572999313aSBarry Smith so this routine is rarely needed. 11582999313aSBarry Smith 11592999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 11602999313aSBarry Smith decreased by one. 11612999313aSBarry Smith 11622999313aSBarry Smith Level: developer 11632999313aSBarry Smith 11642999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 11652999313aSBarry Smith 11662999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 11672999313aSBarry Smith @*/ 11687087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 11692999313aSBarry Smith { 11702999313aSBarry Smith PetscErrorCode ierr; 11712999313aSBarry Smith 11722999313aSBarry Smith PetscFunctionBegin; 11730700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11740700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 11752999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 11767dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1177906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 11782999313aSBarry Smith snes->ksp = ksp; 11792999313aSBarry Smith PetscFunctionReturn(0); 11802999313aSBarry Smith } 11812999313aSBarry Smith 11827adad957SLisandro Dalcin #if 0 11832999313aSBarry Smith #undef __FUNCT__ 11844a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 11856849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1186e24b481bSBarry Smith { 1187e24b481bSBarry Smith PetscFunctionBegin; 1188e24b481bSBarry Smith PetscFunctionReturn(0); 1189e24b481bSBarry Smith } 11907adad957SLisandro Dalcin #endif 1191e24b481bSBarry Smith 11929b94acceSBarry Smith /* -----------------------------------------------------------*/ 11934a2ae208SSatish Balay #undef __FUNCT__ 11944a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 119552baeb72SSatish Balay /*@ 11969b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 11979b94acceSBarry Smith 1198c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1199c7afd0dbSLois Curfman McInnes 1200c7afd0dbSLois Curfman McInnes Input Parameters: 1201906ed7ccSBarry Smith . comm - MPI communicator 12029b94acceSBarry Smith 12039b94acceSBarry Smith Output Parameter: 12049b94acceSBarry Smith . outsnes - the new SNES context 12059b94acceSBarry Smith 1206c7afd0dbSLois Curfman McInnes Options Database Keys: 1207c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1208c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1209c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1210c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1211c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1212c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1213c1f60f51SBarry Smith 121436851e7fSLois Curfman McInnes Level: beginner 121536851e7fSLois Curfman McInnes 12169b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 12179b94acceSBarry Smith 1218a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1219a8054027SBarry Smith 12209b94acceSBarry Smith @*/ 12217087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 12229b94acceSBarry Smith { 1223dfbe8321SBarry Smith PetscErrorCode ierr; 12249b94acceSBarry Smith SNES snes; 1225fa9f3622SBarry Smith SNESKSPEW *kctx; 122637fcc0dbSBarry Smith 12273a40ed3dSBarry Smith PetscFunctionBegin; 1228ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 12298ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 12308ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 12318ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 12328ba1e511SMatthew Knepley #endif 12338ba1e511SMatthew Knepley 12343194b578SJed Brown ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 12357adad957SLisandro Dalcin 123685385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 12372c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 12389b94acceSBarry Smith snes->max_its = 50; 12399750a799SBarry Smith snes->max_funcs = 10000; 12409b94acceSBarry Smith snes->norm = 0.0; 1241b4874afaSBarry Smith snes->rtol = 1.e-8; 1242b4874afaSBarry Smith snes->ttol = 0.0; 124370441072SBarry Smith snes->abstol = 1.e-50; 12449b94acceSBarry Smith snes->xtol = 1.e-8; 12454b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 12469b94acceSBarry Smith snes->nfuncs = 0; 124750ffb88aSMatthew Knepley snes->numFailures = 0; 124850ffb88aSMatthew Knepley snes->maxFailures = 1; 12497a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1250e35cf81dSBarry Smith snes->lagjacobian = 1; 1251a8054027SBarry Smith snes->lagpreconditioner = 1; 1252639f9d9dSBarry Smith snes->numbermonitors = 0; 12539b94acceSBarry Smith snes->data = 0; 12544dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1255186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 12566f24a144SLois Curfman McInnes snes->nwork = 0; 125758c9b817SLisandro Dalcin snes->work = 0; 125858c9b817SLisandro Dalcin snes->nvwork = 0; 125958c9b817SLisandro Dalcin snes->vwork = 0; 1260758f92a0SBarry Smith snes->conv_hist_len = 0; 1261758f92a0SBarry Smith snes->conv_hist_max = 0; 1262758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1263758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1264758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1265184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 126689b92e6fSPeter Brune snes->gssweeps = 1; 12679b94acceSBarry Smith 1268ea630c6eSPeter Brune snes->ops->linesearch = PETSC_NULL; 1269ea630c6eSPeter Brune snes->precheck = PETSC_NULL; 1270ea630c6eSPeter Brune snes->ops->precheckstep = PETSC_NULL; 1271ea630c6eSPeter Brune snes->postcheck = PETSC_NULL; 1272ea630c6eSPeter Brune snes->ops->postcheckstep= PETSC_NULL; 1273ea630c6eSPeter Brune 12743d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 12753d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 12763d4c4710SBarry Smith 12779b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 127838f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 12799b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 12809b94acceSBarry Smith kctx->version = 2; 12819b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 12829b94acceSBarry Smith this was too large for some test cases */ 128375567043SBarry Smith kctx->rtol_last = 0.0; 12849b94acceSBarry Smith kctx->rtol_max = .9; 12859b94acceSBarry Smith kctx->gamma = 1.0; 128662d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 128771f87433Sdalcinl kctx->alpha2 = kctx->alpha; 12889b94acceSBarry Smith kctx->threshold = .1; 128975567043SBarry Smith kctx->lresid_last = 0.0; 129075567043SBarry Smith kctx->norm_last = 0.0; 12919b94acceSBarry Smith 12929b94acceSBarry Smith *outsnes = snes; 12933a40ed3dSBarry Smith PetscFunctionReturn(0); 12949b94acceSBarry Smith } 12959b94acceSBarry Smith 12964a2ae208SSatish Balay #undef __FUNCT__ 12974a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 12989b94acceSBarry Smith /*@C 12999b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 13009b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 13019b94acceSBarry Smith equations. 13029b94acceSBarry Smith 13033f9fe445SBarry Smith Logically Collective on SNES 1304fee21e36SBarry Smith 1305c7afd0dbSLois Curfman McInnes Input Parameters: 1306c7afd0dbSLois Curfman McInnes + snes - the SNES context 1307c7afd0dbSLois Curfman McInnes . r - vector to store function value 1308de044059SHong Zhang . func - function evaluation routine 1309c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1310c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 13119b94acceSBarry Smith 1312c7afd0dbSLois Curfman McInnes Calling sequence of func: 13138d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1314c7afd0dbSLois Curfman McInnes 1315c586c404SJed Brown + snes - the SNES context 1316c586c404SJed Brown . x - state at which to evaluate residual 1317c586c404SJed Brown . f - vector to put residual 1318c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 13199b94acceSBarry Smith 13209b94acceSBarry Smith Notes: 13219b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 13229b94acceSBarry Smith $ f'(x) x = -f(x), 1323c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 13249b94acceSBarry Smith 132536851e7fSLois Curfman McInnes Level: beginner 132636851e7fSLois Curfman McInnes 13279b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 13289b94acceSBarry Smith 13298b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard() 13309b94acceSBarry Smith @*/ 13317087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 13329b94acceSBarry Smith { 133385385478SLisandro Dalcin PetscErrorCode ierr; 13346cab3a1bSJed Brown DM dm; 13356cab3a1bSJed Brown 13363a40ed3dSBarry Smith PetscFunctionBegin; 13370700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1338d2a683ecSLisandro Dalcin if (r) { 1339d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1340d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 134185385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 13426bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 134385385478SLisandro Dalcin snes->vec_func = r; 1344d2a683ecSLisandro Dalcin } 13456cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 13466cab3a1bSJed Brown ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr); 13473a40ed3dSBarry Smith PetscFunctionReturn(0); 13489b94acceSBarry Smith } 13499b94acceSBarry Smith 1350646217ecSPeter Brune 1351646217ecSPeter Brune #undef __FUNCT__ 1352646217ecSPeter Brune #define __FUNCT__ "SNESSetGS" 1353c79ef259SPeter Brune /*@C 1354c79ef259SPeter Brune SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for 1355c79ef259SPeter Brune use with composed nonlinear solvers. 1356c79ef259SPeter Brune 1357c79ef259SPeter Brune Input Parameters: 1358c79ef259SPeter Brune + snes - the SNES context 1359c79ef259SPeter Brune . gsfunc - function evaluation routine 1360c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 1361c79ef259SPeter Brune smoother evaluation routine (may be PETSC_NULL) 1362c79ef259SPeter Brune 1363c79ef259SPeter Brune Calling sequence of func: 1364c79ef259SPeter Brune $ func (SNES snes,Vec x,Vec b,void *ctx); 1365c79ef259SPeter Brune 1366c79ef259SPeter Brune + X - solution vector 1367c79ef259SPeter Brune . B - RHS vector 1368d28543b3SPeter Brune - ctx - optional user-defined Gauss-Seidel context 1369c79ef259SPeter Brune 1370c79ef259SPeter Brune Notes: 1371c79ef259SPeter Brune The GS routines are used by the composed nonlinear solver to generate 1372c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1373c79ef259SPeter Brune 1374d28543b3SPeter Brune Level: intermediate 1375c79ef259SPeter Brune 1376d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1377c79ef259SPeter Brune 1378c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS() 1379c79ef259SPeter Brune @*/ 13806cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx) 13816cab3a1bSJed Brown { 13826cab3a1bSJed Brown PetscErrorCode ierr; 13836cab3a1bSJed Brown DM dm; 13846cab3a1bSJed Brown 1385646217ecSPeter Brune PetscFunctionBegin; 13866cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13876cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 13886cab3a1bSJed Brown ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr); 1389646217ecSPeter Brune PetscFunctionReturn(0); 1390646217ecSPeter Brune } 1391646217ecSPeter Brune 1392d25893d9SBarry Smith #undef __FUNCT__ 139389b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps" 139489b92e6fSPeter Brune /*@ 139589b92e6fSPeter Brune SNESSetGSSweeps - Sets the number of sweeps of GS to use. 139689b92e6fSPeter Brune 139789b92e6fSPeter Brune Input Parameters: 139889b92e6fSPeter Brune + snes - the SNES context 139989b92e6fSPeter Brune - sweeps - the number of sweeps of GS to perform. 140089b92e6fSPeter Brune 140189b92e6fSPeter Brune Level: intermediate 140289b92e6fSPeter Brune 140389b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 140489b92e6fSPeter Brune 140589b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps() 140689b92e6fSPeter Brune @*/ 140789b92e6fSPeter Brune 140889b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) { 140989b92e6fSPeter Brune PetscFunctionBegin; 141089b92e6fSPeter Brune snes->gssweeps = sweeps; 141189b92e6fSPeter Brune PetscFunctionReturn(0); 141289b92e6fSPeter Brune } 141389b92e6fSPeter Brune 141489b92e6fSPeter Brune 141589b92e6fSPeter Brune #undef __FUNCT__ 141689b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps" 141789b92e6fSPeter Brune /*@ 141889b92e6fSPeter Brune SNESGetGSSweeps - Gets the number of sweeps GS will use. 141989b92e6fSPeter Brune 142089b92e6fSPeter Brune Input Parameters: 142189b92e6fSPeter Brune . snes - the SNES context 142289b92e6fSPeter Brune 142389b92e6fSPeter Brune Output Parameters: 142489b92e6fSPeter Brune . sweeps - the number of sweeps of GS to perform. 142589b92e6fSPeter Brune 142689b92e6fSPeter Brune Level: intermediate 142789b92e6fSPeter Brune 142889b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 142989b92e6fSPeter Brune 143089b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps() 143189b92e6fSPeter Brune @*/ 143289b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) { 143389b92e6fSPeter Brune PetscFunctionBegin; 143489b92e6fSPeter Brune *sweeps = snes->gssweeps; 143589b92e6fSPeter Brune PetscFunctionReturn(0); 143689b92e6fSPeter Brune } 143789b92e6fSPeter Brune 143889b92e6fSPeter Brune #undef __FUNCT__ 14398b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 14408b0a5094SBarry Smith PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 14418b0a5094SBarry Smith { 14428b0a5094SBarry Smith PetscErrorCode ierr; 14436cab3a1bSJed Brown void *functx,*jacctx; 14446cab3a1bSJed Brown 14458b0a5094SBarry Smith PetscFunctionBegin; 14466cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 14476cab3a1bSJed Brown ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr); 14488b0a5094SBarry Smith /* A(x)*x - b(x) */ 14496cab3a1bSJed Brown ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr); 14506cab3a1bSJed Brown ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr); 14518b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 14528b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 14538b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 14548b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 14558b0a5094SBarry Smith PetscFunctionReturn(0); 14568b0a5094SBarry Smith } 14578b0a5094SBarry Smith 14588b0a5094SBarry Smith #undef __FUNCT__ 14598b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 14608b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 14618b0a5094SBarry Smith { 14628b0a5094SBarry Smith PetscFunctionBegin; 14638b0a5094SBarry Smith *flag = snes->matstruct; 14648b0a5094SBarry Smith PetscFunctionReturn(0); 14658b0a5094SBarry Smith } 14668b0a5094SBarry Smith 14678b0a5094SBarry Smith #undef __FUNCT__ 14688b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 14698b0a5094SBarry Smith /*@C 14700d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 14718b0a5094SBarry Smith 14728b0a5094SBarry Smith Logically Collective on SNES 14738b0a5094SBarry Smith 14748b0a5094SBarry Smith Input Parameters: 14758b0a5094SBarry Smith + snes - the SNES context 14768b0a5094SBarry Smith . r - vector to store function value 14778b0a5094SBarry Smith . func - function evaluation routine 14788b0a5094SBarry 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) 14798b0a5094SBarry Smith . mat - matrix to store A 14808b0a5094SBarry Smith . mfunc - function to compute matrix value 14818b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 14828b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 14838b0a5094SBarry Smith 14848b0a5094SBarry Smith Calling sequence of func: 14858b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 14868b0a5094SBarry Smith 14878b0a5094SBarry Smith + f - function vector 14888b0a5094SBarry Smith - ctx - optional user-defined function context 14898b0a5094SBarry Smith 14908b0a5094SBarry Smith Calling sequence of mfunc: 14918b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 14928b0a5094SBarry Smith 14938b0a5094SBarry Smith + x - input vector 14948b0a5094SBarry 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(), 14958b0a5094SBarry Smith normally just pass mat in this location 14968b0a5094SBarry Smith . mat - form A(x) matrix 14978b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 14988b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 14998b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 15008b0a5094SBarry Smith 15018b0a5094SBarry Smith Notes: 15028b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 15038b0a5094SBarry Smith 15048b0a5094SBarry 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} 15058b0a5094SBarry 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. 15068b0a5094SBarry Smith 15078b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 15088b0a5094SBarry Smith 15090d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 15100d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 15118b0a5094SBarry Smith 15128b0a5094SBarry 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 15138b0a5094SBarry 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 15148b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 15158b0a5094SBarry Smith 15168b0a5094SBarry Smith Level: beginner 15178b0a5094SBarry Smith 15188b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 15198b0a5094SBarry Smith 15200d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard() 15218b0a5094SBarry Smith @*/ 15228b0a5094SBarry 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) 15238b0a5094SBarry Smith { 15248b0a5094SBarry Smith PetscErrorCode ierr; 15258b0a5094SBarry Smith PetscFunctionBegin; 15268b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15278b0a5094SBarry Smith snes->ops->computepfunction = func; 15288b0a5094SBarry Smith snes->ops->computepjacobian = mfunc; 15298b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 15308b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 15318b0a5094SBarry Smith PetscFunctionReturn(0); 15328b0a5094SBarry Smith } 15338b0a5094SBarry Smith 15348b0a5094SBarry Smith #undef __FUNCT__ 1535d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1536d25893d9SBarry Smith /*@C 1537d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1538d25893d9SBarry Smith 1539d25893d9SBarry Smith Logically Collective on SNES 1540d25893d9SBarry Smith 1541d25893d9SBarry Smith Input Parameters: 1542d25893d9SBarry Smith + snes - the SNES context 1543d25893d9SBarry Smith . func - function evaluation routine 1544d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1545d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1546d25893d9SBarry Smith 1547d25893d9SBarry Smith Calling sequence of func: 1548d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1549d25893d9SBarry Smith 1550d25893d9SBarry Smith . f - function vector 1551d25893d9SBarry Smith - ctx - optional user-defined function context 1552d25893d9SBarry Smith 1553d25893d9SBarry Smith Level: intermediate 1554d25893d9SBarry Smith 1555d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1556d25893d9SBarry Smith 1557d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1558d25893d9SBarry Smith @*/ 1559d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1560d25893d9SBarry Smith { 1561d25893d9SBarry Smith PetscFunctionBegin; 1562d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1563d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1564d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1565d25893d9SBarry Smith PetscFunctionReturn(0); 1566d25893d9SBarry Smith } 1567d25893d9SBarry Smith 15683ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 15693ab0aad5SBarry Smith #undef __FUNCT__ 15701096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 15711096aae1SMatthew Knepley /*@C 15721096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 15731096aae1SMatthew Knepley it assumes a zero right hand side. 15741096aae1SMatthew Knepley 15753f9fe445SBarry Smith Logically Collective on SNES 15761096aae1SMatthew Knepley 15771096aae1SMatthew Knepley Input Parameter: 15781096aae1SMatthew Knepley . snes - the SNES context 15791096aae1SMatthew Knepley 15801096aae1SMatthew Knepley Output Parameter: 1581bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 15821096aae1SMatthew Knepley 15831096aae1SMatthew Knepley Level: intermediate 15841096aae1SMatthew Knepley 15851096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 15861096aae1SMatthew Knepley 158785385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 15881096aae1SMatthew Knepley @*/ 15897087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 15901096aae1SMatthew Knepley { 15911096aae1SMatthew Knepley PetscFunctionBegin; 15920700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15931096aae1SMatthew Knepley PetscValidPointer(rhs,2); 159485385478SLisandro Dalcin *rhs = snes->vec_rhs; 15951096aae1SMatthew Knepley PetscFunctionReturn(0); 15961096aae1SMatthew Knepley } 15971096aae1SMatthew Knepley 15981096aae1SMatthew Knepley #undef __FUNCT__ 15994a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 16009b94acceSBarry Smith /*@ 160136851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 16029b94acceSBarry Smith SNESSetFunction(). 16039b94acceSBarry Smith 1604c7afd0dbSLois Curfman McInnes Collective on SNES 1605c7afd0dbSLois Curfman McInnes 16069b94acceSBarry Smith Input Parameters: 1607c7afd0dbSLois Curfman McInnes + snes - the SNES context 1608c7afd0dbSLois Curfman McInnes - x - input vector 16099b94acceSBarry Smith 16109b94acceSBarry Smith Output Parameter: 16113638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 16129b94acceSBarry Smith 16131bffabb2SLois Curfman McInnes Notes: 161436851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 161536851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 161636851e7fSLois Curfman McInnes themselves. 161736851e7fSLois Curfman McInnes 161836851e7fSLois Curfman McInnes Level: developer 161936851e7fSLois Curfman McInnes 16209b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 16219b94acceSBarry Smith 1622a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 16239b94acceSBarry Smith @*/ 16247087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 16259b94acceSBarry Smith { 1626dfbe8321SBarry Smith PetscErrorCode ierr; 16276cab3a1bSJed Brown DM dm; 16286cab3a1bSJed Brown SNESDM sdm; 16299b94acceSBarry Smith 16303a40ed3dSBarry Smith PetscFunctionBegin; 16310700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16320700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 16330700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1634c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1635c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 16364ec14c9cSBarry Smith VecValidValues(x,2,PETSC_TRUE); 1637184914b5SBarry Smith 16386cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 16396cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 1640d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 16416cab3a1bSJed Brown if (sdm->computefunction) { 1642d64ed03dSBarry Smith PetscStackPush("SNES user function"); 16436cab3a1bSJed Brown ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 1644d64ed03dSBarry Smith PetscStackPop; 164573250ac0SBarry Smith } else if (snes->dm) { 1646644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1647c90fad12SPeter Brune } else if (snes->vec_rhs) { 1648c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1649644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 165085385478SLisandro Dalcin if (snes->vec_rhs) { 165185385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 16523ab0aad5SBarry Smith } 1653ae3c334cSLois Curfman McInnes snes->nfuncs++; 1654d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 16554ec14c9cSBarry Smith VecValidValues(y,3,PETSC_FALSE); 16563a40ed3dSBarry Smith PetscFunctionReturn(0); 16579b94acceSBarry Smith } 16589b94acceSBarry Smith 16594a2ae208SSatish Balay #undef __FUNCT__ 1660646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1661c79ef259SPeter Brune /*@ 1662c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1663c79ef259SPeter Brune SNESSetGS(). 1664c79ef259SPeter Brune 1665c79ef259SPeter Brune Collective on SNES 1666c79ef259SPeter Brune 1667c79ef259SPeter Brune Input Parameters: 1668c79ef259SPeter Brune + snes - the SNES context 1669c79ef259SPeter Brune . x - input vector 1670c79ef259SPeter Brune - b - rhs vector 1671c79ef259SPeter Brune 1672c79ef259SPeter Brune Output Parameter: 1673c79ef259SPeter Brune . x - new solution vector 1674c79ef259SPeter Brune 1675c79ef259SPeter Brune Notes: 1676c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1677c79ef259SPeter Brune implementations, so most users would not generally call this routine 1678c79ef259SPeter Brune themselves. 1679c79ef259SPeter Brune 1680c79ef259SPeter Brune Level: developer 1681c79ef259SPeter Brune 1682c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1683c79ef259SPeter Brune 1684c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1685c79ef259SPeter Brune @*/ 1686646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1687646217ecSPeter Brune { 1688646217ecSPeter Brune PetscErrorCode ierr; 168989b92e6fSPeter Brune PetscInt i; 16906cab3a1bSJed Brown DM dm; 16916cab3a1bSJed Brown SNESDM sdm; 1692646217ecSPeter Brune 1693646217ecSPeter Brune PetscFunctionBegin; 1694646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1695646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1696646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1697646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 1698646217ecSPeter Brune if(b) PetscCheckSameComm(snes,1,b,3); 16994ec14c9cSBarry Smith if (b) VecValidValues(b,2,PETSC_TRUE); 1700701cf23dSPeter Brune ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 17016cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 17026cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 17036cab3a1bSJed Brown if (sdm->computegs) { 170489b92e6fSPeter Brune for (i = 0; i < snes->gssweeps; i++) { 1705646217ecSPeter Brune PetscStackPush("SNES user GS"); 17066cab3a1bSJed Brown ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 1707646217ecSPeter Brune PetscStackPop; 170889b92e6fSPeter Brune } 1709646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 1710701cf23dSPeter Brune ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 17114ec14c9cSBarry Smith VecValidValues(x,3,PETSC_FALSE); 1712646217ecSPeter Brune PetscFunctionReturn(0); 1713646217ecSPeter Brune } 1714646217ecSPeter Brune 1715646217ecSPeter Brune 1716646217ecSPeter Brune #undef __FUNCT__ 17174a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 171862fef451SLois Curfman McInnes /*@ 171962fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 172062fef451SLois Curfman McInnes set with SNESSetJacobian(). 172162fef451SLois Curfman McInnes 1722c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1723c7afd0dbSLois Curfman McInnes 172462fef451SLois Curfman McInnes Input Parameters: 1725c7afd0dbSLois Curfman McInnes + snes - the SNES context 1726c7afd0dbSLois Curfman McInnes - x - input vector 172762fef451SLois Curfman McInnes 172862fef451SLois Curfman McInnes Output Parameters: 1729c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 173062fef451SLois Curfman McInnes . B - optional preconditioning matrix 17312b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1732fee21e36SBarry Smith 1733e35cf81dSBarry Smith Options Database Keys: 1734e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1735693365a8SJed Brown . -snes_lag_jacobian <lag> 1736693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1737693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1738693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 17394c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1740c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 1741c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 1742c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 1743c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 1744c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 17454c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 1746c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 1747c01495d3SJed Brown 1748e35cf81dSBarry Smith 174962fef451SLois Curfman McInnes Notes: 175062fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 175162fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 175262fef451SLois Curfman McInnes 175394b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1754dc5a77f8SLois Curfman McInnes flag parameter. 175562fef451SLois Curfman McInnes 175636851e7fSLois Curfman McInnes Level: developer 175736851e7fSLois Curfman McInnes 175862fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 175962fef451SLois Curfman McInnes 1760e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 176162fef451SLois Curfman McInnes @*/ 17627087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 17639b94acceSBarry Smith { 1764dfbe8321SBarry Smith PetscErrorCode ierr; 1765ace3abfcSBarry Smith PetscBool flag; 17666cab3a1bSJed Brown DM dm; 17676cab3a1bSJed Brown SNESDM sdm; 17683a40ed3dSBarry Smith 17693a40ed3dSBarry Smith PetscFunctionBegin; 17700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 17710700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 17724482741eSBarry Smith PetscValidPointer(flg,5); 1773c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 17744ec14c9cSBarry Smith VecValidValues(X,2,PETSC_TRUE); 17756cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 17766cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 17776cab3a1bSJed Brown if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 1778ebd3b9afSBarry Smith 1779ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1780ebd3b9afSBarry Smith 1781fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 1782fe3ffe1eSBarry Smith snes->lagjacobian = -1; 1783fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1784fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 1785e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1786e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1787ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1788ebd3b9afSBarry Smith if (flag) { 1789ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1790ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1791ebd3b9afSBarry Smith } 1792e35cf81dSBarry Smith PetscFunctionReturn(0); 1793e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1794e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1795e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1796ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1797ebd3b9afSBarry Smith if (flag) { 1798ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1799ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1800ebd3b9afSBarry Smith } 1801e35cf81dSBarry Smith PetscFunctionReturn(0); 1802e35cf81dSBarry Smith } 1803e35cf81dSBarry Smith 1804c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 1805e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1806d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 18076cab3a1bSJed Brown ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr); 1808d64ed03dSBarry Smith PetscStackPop; 1809d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1810a8054027SBarry Smith 18113b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 18123b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 18133b4f5425SBarry Smith snes->lagpreconditioner = -1; 18143b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 1815a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1816a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 1817a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 1818a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1819a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 1820a8054027SBarry Smith } 1821a8054027SBarry Smith 18226d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 18230700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 18240700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 1825693365a8SJed Brown { 1826693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 1827693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 1828693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 1829693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 1830693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 1831693365a8SJed Brown if (flag || flag_draw || flag_contour) { 1832693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 1833693365a8SJed Brown MatStructure mstruct; 1834693365a8SJed Brown PetscViewer vdraw,vstdout; 18356b3a5b13SJed Brown PetscBool flg; 1836693365a8SJed Brown if (flag_operator) { 1837693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 1838693365a8SJed Brown Bexp = Bexp_mine; 1839693365a8SJed Brown } else { 1840693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 1841693365a8SJed Brown ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 1842693365a8SJed Brown if (flg) Bexp = *B; 1843693365a8SJed Brown else { 1844693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 1845693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 1846693365a8SJed Brown Bexp = Bexp_mine; 1847693365a8SJed Brown } 1848693365a8SJed Brown } 1849693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 1850693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 1851693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 1852693365a8SJed Brown if (flag_draw || flag_contour) { 1853693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 1854693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 1855693365a8SJed Brown } else vdraw = PETSC_NULL; 1856693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 1857693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 1858693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 1859693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 1860693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1861693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 1862693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1863693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 1864693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1865693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 1866693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 1867693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 1868693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 1869693365a8SJed Brown } 1870693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 1871693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 1872693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 1873693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 1874693365a8SJed Brown } 1875693365a8SJed Brown } 18764c30e9fbSJed Brown { 18776719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 18786719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 18794c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 18806719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 18814c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 18824c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 18836719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 18846719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 18856719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 18866719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 18874c30e9fbSJed Brown Mat Bfd; 18884c30e9fbSJed Brown MatStructure mstruct; 18894c30e9fbSJed Brown PetscViewer vdraw,vstdout; 18904c30e9fbSJed Brown ISColoring iscoloring; 18914c30e9fbSJed Brown MatFDColoring matfdcoloring; 18924c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 18934c30e9fbSJed Brown void *funcctx; 18946719d8e4SJed Brown PetscReal norm1,norm2,normmax; 18954c30e9fbSJed Brown 18964c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 18974c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 18984c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 18994c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 19004c30e9fbSJed Brown 19014c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 19024c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 19034c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 19044c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 19054c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 19064c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 19074c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 19084c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 19094c30e9fbSJed Brown 19104c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 19114c30e9fbSJed Brown if (flag_draw || flag_contour) { 19124c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 19134c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 19144c30e9fbSJed Brown } else vdraw = PETSC_NULL; 19154c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 19166719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 19174c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 19184c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 19196719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 19204c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 19214c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 19224c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 19236719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 19244c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 19256719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 19266719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 19274c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 19284c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 19294c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 19304c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 19314c30e9fbSJed Brown } 19324c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 19336719d8e4SJed Brown 19346719d8e4SJed Brown if (flag_threshold) { 19356719d8e4SJed Brown PetscInt bs,rstart,rend,i; 19366719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 19376719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 19386719d8e4SJed Brown for (i=rstart; i<rend; i++) { 19396719d8e4SJed Brown const PetscScalar *ba,*ca; 19406719d8e4SJed Brown const PetscInt *bj,*cj; 19416719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 19426719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 19436719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 19446719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 19456719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 19466719d8e4SJed Brown for (j=0; j<bn; j++) { 19476719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 19486719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 19496719d8e4SJed Brown maxentrycol = bj[j]; 19506719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 19516719d8e4SJed Brown } 19526719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 19536719d8e4SJed Brown maxdiffcol = bj[j]; 19546719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 19556719d8e4SJed Brown } 19566719d8e4SJed Brown if (rdiff > maxrdiff) { 19576719d8e4SJed Brown maxrdiffcol = bj[j]; 19586719d8e4SJed Brown maxrdiff = rdiff; 19596719d8e4SJed Brown } 19606719d8e4SJed Brown } 19616719d8e4SJed Brown if (maxrdiff > 1) { 19626719d8e4SJed 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); 19636719d8e4SJed Brown for (j=0; j<bn; j++) { 19646719d8e4SJed Brown PetscReal rdiff; 19656719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 19666719d8e4SJed Brown if (rdiff > 1) { 19676719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 19686719d8e4SJed Brown } 19696719d8e4SJed Brown } 19706719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 19716719d8e4SJed Brown } 19726719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 19736719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 19746719d8e4SJed Brown } 19756719d8e4SJed Brown } 19764c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 19774c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 19784c30e9fbSJed Brown } 19794c30e9fbSJed Brown } 19803a40ed3dSBarry Smith PetscFunctionReturn(0); 19819b94acceSBarry Smith } 19829b94acceSBarry Smith 19834a2ae208SSatish Balay #undef __FUNCT__ 19844a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 19859b94acceSBarry Smith /*@C 19869b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 1987044dda88SLois Curfman McInnes location to store the matrix. 19889b94acceSBarry Smith 19893f9fe445SBarry Smith Logically Collective on SNES and Mat 1990c7afd0dbSLois Curfman McInnes 19919b94acceSBarry Smith Input Parameters: 1992c7afd0dbSLois Curfman McInnes + snes - the SNES context 19939b94acceSBarry Smith . A - Jacobian matrix 19949b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 1995efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 1996c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1997efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 19989b94acceSBarry Smith 19999b94acceSBarry Smith Calling sequence of func: 20008d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 20019b94acceSBarry Smith 2002c7afd0dbSLois Curfman McInnes + x - input vector 20039b94acceSBarry Smith . A - Jacobian matrix 20049b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 2005ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 20062b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 2007c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 20089b94acceSBarry Smith 20099b94acceSBarry Smith Notes: 201094b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 20112cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 2012ac21db08SLois Curfman McInnes 2013ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 20149b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 20159b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 20169b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 20179b94acceSBarry Smith throughout the global iterations. 20189b94acceSBarry Smith 201916913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 202016913363SBarry Smith each matrix. 202116913363SBarry Smith 2022a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 2023a8a26c1eSJed Brown must be a MatFDColoring. 2024a8a26c1eSJed Brown 2025c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2026c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2027c3cc8fd1SJed Brown 202836851e7fSLois Curfman McInnes Level: beginner 202936851e7fSLois Curfman McInnes 20309b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 20319b94acceSBarry Smith 20323ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 20339b94acceSBarry Smith @*/ 20347087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 20359b94acceSBarry Smith { 2036dfbe8321SBarry Smith PetscErrorCode ierr; 20376cab3a1bSJed Brown DM dm; 20383a7fca6bSBarry Smith 20393a40ed3dSBarry Smith PetscFunctionBegin; 20400700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 20410700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 20420700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 2043c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 204406975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 20456cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 20466cab3a1bSJed Brown ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr); 20473a7fca6bSBarry Smith if (A) { 20487dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 20496bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 20509b94acceSBarry Smith snes->jacobian = A; 20513a7fca6bSBarry Smith } 20523a7fca6bSBarry Smith if (B) { 20537dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 20546bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 20559b94acceSBarry Smith snes->jacobian_pre = B; 20563a7fca6bSBarry Smith } 20573a40ed3dSBarry Smith PetscFunctionReturn(0); 20589b94acceSBarry Smith } 205962fef451SLois Curfman McInnes 20604a2ae208SSatish Balay #undef __FUNCT__ 20614a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 2062c2aafc4cSSatish Balay /*@C 2063b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2064b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2065b4fd4287SBarry Smith 2066c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2067c7afd0dbSLois Curfman McInnes 2068b4fd4287SBarry Smith Input Parameter: 2069b4fd4287SBarry Smith . snes - the nonlinear solver context 2070b4fd4287SBarry Smith 2071b4fd4287SBarry Smith Output Parameters: 2072c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 2073b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 207470e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 207570e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 2076fee21e36SBarry Smith 207736851e7fSLois Curfman McInnes Level: advanced 207836851e7fSLois Curfman McInnes 2079b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 2080b4fd4287SBarry Smith @*/ 20817087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 2082b4fd4287SBarry Smith { 20836cab3a1bSJed Brown PetscErrorCode ierr; 20846cab3a1bSJed Brown DM dm; 20856cab3a1bSJed Brown SNESDM sdm; 20866cab3a1bSJed Brown 20873a40ed3dSBarry Smith PetscFunctionBegin; 20880700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2089b4fd4287SBarry Smith if (A) *A = snes->jacobian; 2090b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 20916cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 20926cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 20936cab3a1bSJed Brown if (func) *func = sdm->computejacobian; 20946cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 20953a40ed3dSBarry Smith PetscFunctionReturn(0); 2096b4fd4287SBarry Smith } 2097b4fd4287SBarry Smith 20989b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 20999b94acceSBarry Smith 21004a2ae208SSatish Balay #undef __FUNCT__ 21014a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 21029b94acceSBarry Smith /*@ 21039b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2104272ac6f2SLois Curfman McInnes of a nonlinear solver. 21059b94acceSBarry Smith 2106fee21e36SBarry Smith Collective on SNES 2107fee21e36SBarry Smith 2108c7afd0dbSLois Curfman McInnes Input Parameters: 210970e92668SMatthew Knepley . snes - the SNES context 2110c7afd0dbSLois Curfman McInnes 2111272ac6f2SLois Curfman McInnes Notes: 2112272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2113272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2114272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2115272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2116272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2117272ac6f2SLois Curfman McInnes 211836851e7fSLois Curfman McInnes Level: advanced 211936851e7fSLois Curfman McInnes 21209b94acceSBarry Smith .keywords: SNES, nonlinear, setup 21219b94acceSBarry Smith 21229b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 21239b94acceSBarry Smith @*/ 21247087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 21259b94acceSBarry Smith { 2126dfbe8321SBarry Smith PetscErrorCode ierr; 21276cab3a1bSJed Brown DM dm; 21286cab3a1bSJed Brown SNESDM sdm; 21293a40ed3dSBarry Smith 21303a40ed3dSBarry Smith PetscFunctionBegin; 21310700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 21324dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 21339b94acceSBarry Smith 21347adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 213585385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 213685385478SLisandro Dalcin } 213785385478SLisandro Dalcin 2138a63bb30eSJed Brown ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 213917186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 214058c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 214158c9b817SLisandro Dalcin 214258c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 214358c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 214458c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 214558c9b817SLisandro Dalcin } 214658c9b817SLisandro Dalcin 21476cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 21486cab3a1bSJed Brown ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */ 21496cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 21506cab3a1bSJed Brown if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc"); 21516cab3a1bSJed Brown if (!snes->vec_func) { 21526cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2153214df951SJed Brown } 2154efd51863SBarry Smith 2155b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 2156b710008aSBarry Smith 21579e764e56SPeter Brune if (!snes->linesearch) {ierr = SNESGetPetscLineSearch(snes, &snes->linesearch);} 21589e764e56SPeter Brune 2159d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 2160d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2161d25893d9SBarry Smith } 2162d25893d9SBarry Smith 2163410397dcSLisandro Dalcin if (snes->ops->setup) { 2164410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2165410397dcSLisandro Dalcin } 216658c9b817SLisandro Dalcin 21677aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 21683a40ed3dSBarry Smith PetscFunctionReturn(0); 21699b94acceSBarry Smith } 21709b94acceSBarry Smith 21714a2ae208SSatish Balay #undef __FUNCT__ 217237596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 217337596af1SLisandro Dalcin /*@ 217437596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 217537596af1SLisandro Dalcin 217637596af1SLisandro Dalcin Collective on SNES 217737596af1SLisandro Dalcin 217837596af1SLisandro Dalcin Input Parameter: 217937596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 218037596af1SLisandro Dalcin 2181d25893d9SBarry Smith Level: intermediate 2182d25893d9SBarry Smith 2183d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 218437596af1SLisandro Dalcin 218537596af1SLisandro Dalcin .keywords: SNES, destroy 218637596af1SLisandro Dalcin 218737596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 218837596af1SLisandro Dalcin @*/ 218937596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 219037596af1SLisandro Dalcin { 219137596af1SLisandro Dalcin PetscErrorCode ierr; 219237596af1SLisandro Dalcin 219337596af1SLisandro Dalcin PetscFunctionBegin; 219437596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2195d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2196d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2197d25893d9SBarry Smith snes->user = PETSC_NULL; 2198d25893d9SBarry Smith } 21998a23116dSBarry Smith if (snes->pc) { 22008a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 22018a23116dSBarry Smith } 22028a23116dSBarry Smith 220337596af1SLisandro Dalcin if (snes->ops->reset) { 220437596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 220537596af1SLisandro Dalcin } 22069e764e56SPeter Brune if (snes->ksp) { 22079e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 22089e764e56SPeter Brune } 22099e764e56SPeter Brune 22109e764e56SPeter Brune if (snes->linesearch) { 22119e764e56SPeter Brune ierr = PetscLineSearchReset(snes->linesearch);CHKERRQ(ierr); 22129e764e56SPeter Brune } 22139e764e56SPeter Brune 22146bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 22156bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 22166bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 22176bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 22186bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 22196bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2220c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2221c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 222237596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 222337596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 222437596af1SLisandro Dalcin PetscFunctionReturn(0); 222537596af1SLisandro Dalcin } 222637596af1SLisandro Dalcin 222737596af1SLisandro Dalcin #undef __FUNCT__ 22284a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 222952baeb72SSatish Balay /*@ 22309b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 22319b94acceSBarry Smith with SNESCreate(). 22329b94acceSBarry Smith 2233c7afd0dbSLois Curfman McInnes Collective on SNES 2234c7afd0dbSLois Curfman McInnes 22359b94acceSBarry Smith Input Parameter: 22369b94acceSBarry Smith . snes - the SNES context 22379b94acceSBarry Smith 223836851e7fSLois Curfman McInnes Level: beginner 223936851e7fSLois Curfman McInnes 22409b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 22419b94acceSBarry Smith 224263a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 22439b94acceSBarry Smith @*/ 22446bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 22459b94acceSBarry Smith { 22466849ba73SBarry Smith PetscErrorCode ierr; 22473a40ed3dSBarry Smith 22483a40ed3dSBarry Smith PetscFunctionBegin; 22496bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 22506bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 22516bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2252d4bb536fSBarry Smith 22536bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 22548a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 22556b8b9a38SLisandro Dalcin 2256be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 22576bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 22586bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 22596d4c513bSLisandro Dalcin 22606bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 22616bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 22629e764e56SPeter Brune ierr = PetscLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 22636b8b9a38SLisandro Dalcin 22646bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 22656bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 22666bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 22676b8b9a38SLisandro Dalcin } 22686bf464f9SBarry Smith if ((*snes)->conv_malloc) { 22696bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 22706bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 227158c9b817SLisandro Dalcin } 2272ea630c6eSPeter Brune ierr = PetscViewerDestroy(&(*snes)->ls_monitor);CHKERRQ(ierr); 22736bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2274a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 22753a40ed3dSBarry Smith PetscFunctionReturn(0); 22769b94acceSBarry Smith } 22779b94acceSBarry Smith 22789b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 22799b94acceSBarry Smith 22804a2ae208SSatish Balay #undef __FUNCT__ 2281a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2282a8054027SBarry Smith /*@ 2283a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2284a8054027SBarry Smith 22853f9fe445SBarry Smith Logically Collective on SNES 2286a8054027SBarry Smith 2287a8054027SBarry Smith Input Parameters: 2288a8054027SBarry Smith + snes - the SNES context 2289a8054027SBarry 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 22903b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2291a8054027SBarry Smith 2292a8054027SBarry Smith Options Database Keys: 2293a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2294a8054027SBarry Smith 2295a8054027SBarry Smith Notes: 2296a8054027SBarry Smith The default is 1 2297a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2298a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2299a8054027SBarry Smith 2300a8054027SBarry Smith Level: intermediate 2301a8054027SBarry Smith 2302a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2303a8054027SBarry Smith 2304e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2305a8054027SBarry Smith 2306a8054027SBarry Smith @*/ 23077087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2308a8054027SBarry Smith { 2309a8054027SBarry Smith PetscFunctionBegin; 23100700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2311e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2312e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2313c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2314a8054027SBarry Smith snes->lagpreconditioner = lag; 2315a8054027SBarry Smith PetscFunctionReturn(0); 2316a8054027SBarry Smith } 2317a8054027SBarry Smith 2318a8054027SBarry Smith #undef __FUNCT__ 2319efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2320efd51863SBarry Smith /*@ 2321efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2322efd51863SBarry Smith 2323efd51863SBarry Smith Logically Collective on SNES 2324efd51863SBarry Smith 2325efd51863SBarry Smith Input Parameters: 2326efd51863SBarry Smith + snes - the SNES context 2327efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2328efd51863SBarry Smith 2329efd51863SBarry Smith Options Database Keys: 2330efd51863SBarry Smith . -snes_grid_sequence <steps> 2331efd51863SBarry Smith 2332efd51863SBarry Smith Level: intermediate 2333efd51863SBarry Smith 2334c0df2a02SJed Brown Notes: 2335c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2336c0df2a02SJed Brown 2337efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2338efd51863SBarry Smith 2339efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2340efd51863SBarry Smith 2341efd51863SBarry Smith @*/ 2342efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2343efd51863SBarry Smith { 2344efd51863SBarry Smith PetscFunctionBegin; 2345efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2346efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2347efd51863SBarry Smith snes->gridsequence = steps; 2348efd51863SBarry Smith PetscFunctionReturn(0); 2349efd51863SBarry Smith } 2350efd51863SBarry Smith 2351efd51863SBarry Smith #undef __FUNCT__ 2352a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2353a8054027SBarry Smith /*@ 2354a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2355a8054027SBarry Smith 23563f9fe445SBarry Smith Not Collective 2357a8054027SBarry Smith 2358a8054027SBarry Smith Input Parameter: 2359a8054027SBarry Smith . snes - the SNES context 2360a8054027SBarry Smith 2361a8054027SBarry Smith Output Parameter: 2362a8054027SBarry 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 23633b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2364a8054027SBarry Smith 2365a8054027SBarry Smith Options Database Keys: 2366a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2367a8054027SBarry Smith 2368a8054027SBarry Smith Notes: 2369a8054027SBarry Smith The default is 1 2370a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2371a8054027SBarry Smith 2372a8054027SBarry Smith Level: intermediate 2373a8054027SBarry Smith 2374a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2375a8054027SBarry Smith 2376a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2377a8054027SBarry Smith 2378a8054027SBarry Smith @*/ 23797087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2380a8054027SBarry Smith { 2381a8054027SBarry Smith PetscFunctionBegin; 23820700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2383a8054027SBarry Smith *lag = snes->lagpreconditioner; 2384a8054027SBarry Smith PetscFunctionReturn(0); 2385a8054027SBarry Smith } 2386a8054027SBarry Smith 2387a8054027SBarry Smith #undef __FUNCT__ 2388e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2389e35cf81dSBarry Smith /*@ 2390e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2391e35cf81dSBarry Smith often the preconditioner is rebuilt. 2392e35cf81dSBarry Smith 23933f9fe445SBarry Smith Logically Collective on SNES 2394e35cf81dSBarry Smith 2395e35cf81dSBarry Smith Input Parameters: 2396e35cf81dSBarry Smith + snes - the SNES context 2397e35cf81dSBarry 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 2398fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2399e35cf81dSBarry Smith 2400e35cf81dSBarry Smith Options Database Keys: 2401e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2402e35cf81dSBarry Smith 2403e35cf81dSBarry Smith Notes: 2404e35cf81dSBarry Smith The default is 1 2405e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2406fe3ffe1eSBarry 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 2407fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2408e35cf81dSBarry Smith 2409e35cf81dSBarry Smith Level: intermediate 2410e35cf81dSBarry Smith 2411e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2412e35cf81dSBarry Smith 2413e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2414e35cf81dSBarry Smith 2415e35cf81dSBarry Smith @*/ 24167087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2417e35cf81dSBarry Smith { 2418e35cf81dSBarry Smith PetscFunctionBegin; 24190700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2420e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2421e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2422c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2423e35cf81dSBarry Smith snes->lagjacobian = lag; 2424e35cf81dSBarry Smith PetscFunctionReturn(0); 2425e35cf81dSBarry Smith } 2426e35cf81dSBarry Smith 2427e35cf81dSBarry Smith #undef __FUNCT__ 2428e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2429e35cf81dSBarry Smith /*@ 2430e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2431e35cf81dSBarry Smith 24323f9fe445SBarry Smith Not Collective 2433e35cf81dSBarry Smith 2434e35cf81dSBarry Smith Input Parameter: 2435e35cf81dSBarry Smith . snes - the SNES context 2436e35cf81dSBarry Smith 2437e35cf81dSBarry Smith Output Parameter: 2438e35cf81dSBarry 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 2439e35cf81dSBarry Smith the Jacobian is built etc. 2440e35cf81dSBarry Smith 2441e35cf81dSBarry Smith Options Database Keys: 2442e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2443e35cf81dSBarry Smith 2444e35cf81dSBarry Smith Notes: 2445e35cf81dSBarry Smith The default is 1 2446e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2447e35cf81dSBarry Smith 2448e35cf81dSBarry Smith Level: intermediate 2449e35cf81dSBarry Smith 2450e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2451e35cf81dSBarry Smith 2452e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2453e35cf81dSBarry Smith 2454e35cf81dSBarry Smith @*/ 24557087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2456e35cf81dSBarry Smith { 2457e35cf81dSBarry Smith PetscFunctionBegin; 24580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2459e35cf81dSBarry Smith *lag = snes->lagjacobian; 2460e35cf81dSBarry Smith PetscFunctionReturn(0); 2461e35cf81dSBarry Smith } 2462e35cf81dSBarry Smith 2463e35cf81dSBarry Smith #undef __FUNCT__ 24644a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 24659b94acceSBarry Smith /*@ 2466d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 24679b94acceSBarry Smith 24683f9fe445SBarry Smith Logically Collective on SNES 2469c7afd0dbSLois Curfman McInnes 24709b94acceSBarry Smith Input Parameters: 2471c7afd0dbSLois Curfman McInnes + snes - the SNES context 247270441072SBarry Smith . abstol - absolute convergence tolerance 247333174efeSLois Curfman McInnes . rtol - relative convergence tolerance 247433174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 247533174efeSLois Curfman McInnes of the change in the solution between steps 247633174efeSLois Curfman McInnes . maxit - maximum number of iterations 2477c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2478fee21e36SBarry Smith 247933174efeSLois Curfman McInnes Options Database Keys: 248070441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2481c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2482c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2483c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2484c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 24859b94acceSBarry Smith 2486d7a720efSLois Curfman McInnes Notes: 24879b94acceSBarry Smith The default maximum number of iterations is 50. 24889b94acceSBarry Smith The default maximum number of function evaluations is 1000. 24899b94acceSBarry Smith 249036851e7fSLois Curfman McInnes Level: intermediate 249136851e7fSLois Curfman McInnes 249233174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 24939b94acceSBarry Smith 24942492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 24959b94acceSBarry Smith @*/ 24967087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 24979b94acceSBarry Smith { 24983a40ed3dSBarry Smith PetscFunctionBegin; 24990700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2500c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2501c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2502c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2503c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2504c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2505c5eb9154SBarry Smith 2506ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2507ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2508ab54825eSJed Brown snes->abstol = abstol; 2509ab54825eSJed Brown } 2510ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2511ab54825eSJed 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); 2512ab54825eSJed Brown snes->rtol = rtol; 2513ab54825eSJed Brown } 2514ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2515ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2516ab54825eSJed Brown snes->xtol = stol; 2517ab54825eSJed Brown } 2518ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2519ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2520ab54825eSJed Brown snes->max_its = maxit; 2521ab54825eSJed Brown } 2522ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2523ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2524ab54825eSJed Brown snes->max_funcs = maxf; 2525ab54825eSJed Brown } 25263a40ed3dSBarry Smith PetscFunctionReturn(0); 25279b94acceSBarry Smith } 25289b94acceSBarry Smith 25294a2ae208SSatish Balay #undef __FUNCT__ 25304a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 25319b94acceSBarry Smith /*@ 253233174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 253333174efeSLois Curfman McInnes 2534c7afd0dbSLois Curfman McInnes Not Collective 2535c7afd0dbSLois Curfman McInnes 253633174efeSLois Curfman McInnes Input Parameters: 2537c7afd0dbSLois Curfman McInnes + snes - the SNES context 253885385478SLisandro Dalcin . atol - absolute convergence tolerance 253933174efeSLois Curfman McInnes . rtol - relative convergence tolerance 254033174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 254133174efeSLois Curfman McInnes of the change in the solution between steps 254233174efeSLois Curfman McInnes . maxit - maximum number of iterations 2543c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2544fee21e36SBarry Smith 254533174efeSLois Curfman McInnes Notes: 254633174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 254733174efeSLois Curfman McInnes 254836851e7fSLois Curfman McInnes Level: intermediate 254936851e7fSLois Curfman McInnes 255033174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 255133174efeSLois Curfman McInnes 255233174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 255333174efeSLois Curfman McInnes @*/ 25547087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 255533174efeSLois Curfman McInnes { 25563a40ed3dSBarry Smith PetscFunctionBegin; 25570700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 255885385478SLisandro Dalcin if (atol) *atol = snes->abstol; 255933174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 256033174efeSLois Curfman McInnes if (stol) *stol = snes->xtol; 256133174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 256233174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 25633a40ed3dSBarry Smith PetscFunctionReturn(0); 256433174efeSLois Curfman McInnes } 256533174efeSLois Curfman McInnes 25664a2ae208SSatish Balay #undef __FUNCT__ 25674a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 256833174efeSLois Curfman McInnes /*@ 25699b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 25709b94acceSBarry Smith 25713f9fe445SBarry Smith Logically Collective on SNES 2572fee21e36SBarry Smith 2573c7afd0dbSLois Curfman McInnes Input Parameters: 2574c7afd0dbSLois Curfman McInnes + snes - the SNES context 2575c7afd0dbSLois Curfman McInnes - tol - tolerance 2576c7afd0dbSLois Curfman McInnes 25779b94acceSBarry Smith Options Database Key: 2578c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 25799b94acceSBarry Smith 258036851e7fSLois Curfman McInnes Level: intermediate 258136851e7fSLois Curfman McInnes 25829b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 25839b94acceSBarry Smith 25842492ecdbSBarry Smith .seealso: SNESSetTolerances() 25859b94acceSBarry Smith @*/ 25867087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 25879b94acceSBarry Smith { 25883a40ed3dSBarry Smith PetscFunctionBegin; 25890700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2590c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 25919b94acceSBarry Smith snes->deltatol = tol; 25923a40ed3dSBarry Smith PetscFunctionReturn(0); 25939b94acceSBarry Smith } 25949b94acceSBarry Smith 2595df9fa365SBarry Smith /* 2596df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2597df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2598df9fa365SBarry Smith macros instead of functions 2599df9fa365SBarry Smith */ 26004a2ae208SSatish Balay #undef __FUNCT__ 2601a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 26027087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2603ce1608b8SBarry Smith { 2604dfbe8321SBarry Smith PetscErrorCode ierr; 2605ce1608b8SBarry Smith 2606ce1608b8SBarry Smith PetscFunctionBegin; 26070700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2608a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2609ce1608b8SBarry Smith PetscFunctionReturn(0); 2610ce1608b8SBarry Smith } 2611ce1608b8SBarry Smith 26124a2ae208SSatish Balay #undef __FUNCT__ 2613a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 26147087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2615df9fa365SBarry Smith { 2616dfbe8321SBarry Smith PetscErrorCode ierr; 2617df9fa365SBarry Smith 2618df9fa365SBarry Smith PetscFunctionBegin; 2619a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2620df9fa365SBarry Smith PetscFunctionReturn(0); 2621df9fa365SBarry Smith } 2622df9fa365SBarry Smith 26234a2ae208SSatish Balay #undef __FUNCT__ 2624a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 26256bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2626df9fa365SBarry Smith { 2627dfbe8321SBarry Smith PetscErrorCode ierr; 2628df9fa365SBarry Smith 2629df9fa365SBarry Smith PetscFunctionBegin; 2630a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2631df9fa365SBarry Smith PetscFunctionReturn(0); 2632df9fa365SBarry Smith } 2633df9fa365SBarry Smith 26347087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2635b271bb04SBarry Smith #undef __FUNCT__ 2636b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 26377087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2638b271bb04SBarry Smith { 2639b271bb04SBarry Smith PetscDrawLG lg; 2640b271bb04SBarry Smith PetscErrorCode ierr; 2641b271bb04SBarry Smith PetscReal x,y,per; 2642b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2643b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2644b271bb04SBarry Smith PetscDraw draw; 2645b271bb04SBarry Smith PetscFunctionBegin; 2646b271bb04SBarry Smith if (!monctx) { 2647b271bb04SBarry Smith MPI_Comm comm; 2648b271bb04SBarry Smith 2649b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2650b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2651b271bb04SBarry Smith } 2652b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2653b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2654b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2655b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2656b271bb04SBarry Smith x = (PetscReal) n; 2657b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2658b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2659b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2660b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2661b271bb04SBarry Smith } 2662b271bb04SBarry Smith 2663b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2664b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2665b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2666b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2667b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2668b271bb04SBarry Smith x = (PetscReal) n; 2669b271bb04SBarry Smith y = 100.0*per; 2670b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2671b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2672b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2673b271bb04SBarry Smith } 2674b271bb04SBarry Smith 2675b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2676b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2677b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2678b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2679b271bb04SBarry Smith x = (PetscReal) n; 2680b271bb04SBarry Smith y = (prev - rnorm)/prev; 2681b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2682b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2683b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2684b271bb04SBarry Smith } 2685b271bb04SBarry Smith 2686b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&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,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2690b271bb04SBarry Smith x = (PetscReal) n; 2691b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2692b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2693b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2694b271bb04SBarry Smith } 2695b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2696b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2697b271bb04SBarry Smith } 2698b271bb04SBarry Smith prev = rnorm; 2699b271bb04SBarry Smith PetscFunctionReturn(0); 2700b271bb04SBarry Smith } 2701b271bb04SBarry Smith 2702b271bb04SBarry Smith #undef __FUNCT__ 2703b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 27047087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2705b271bb04SBarry Smith { 2706b271bb04SBarry Smith PetscErrorCode ierr; 2707b271bb04SBarry Smith 2708b271bb04SBarry Smith PetscFunctionBegin; 2709b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2710b271bb04SBarry Smith PetscFunctionReturn(0); 2711b271bb04SBarry Smith } 2712b271bb04SBarry Smith 2713b271bb04SBarry Smith #undef __FUNCT__ 2714b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 27156bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2716b271bb04SBarry Smith { 2717b271bb04SBarry Smith PetscErrorCode ierr; 2718b271bb04SBarry Smith 2719b271bb04SBarry Smith PetscFunctionBegin; 2720b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2721b271bb04SBarry Smith PetscFunctionReturn(0); 2722b271bb04SBarry Smith } 2723b271bb04SBarry Smith 27247a03ce2fSLisandro Dalcin #undef __FUNCT__ 27257a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 2726228d79bcSJed Brown /*@ 2727228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 2728228d79bcSJed Brown 2729228d79bcSJed Brown Collective on SNES 2730228d79bcSJed Brown 2731228d79bcSJed Brown Input Parameters: 2732228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 2733228d79bcSJed Brown . iter - iteration number 2734228d79bcSJed Brown - rnorm - relative norm of the residual 2735228d79bcSJed Brown 2736228d79bcSJed Brown Notes: 2737228d79bcSJed Brown This routine is called by the SNES implementations. 2738228d79bcSJed Brown It does not typically need to be called by the user. 2739228d79bcSJed Brown 2740228d79bcSJed Brown Level: developer 2741228d79bcSJed Brown 2742228d79bcSJed Brown .seealso: SNESMonitorSet() 2743228d79bcSJed Brown @*/ 27447a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 27457a03ce2fSLisandro Dalcin { 27467a03ce2fSLisandro Dalcin PetscErrorCode ierr; 27477a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 27487a03ce2fSLisandro Dalcin 27497a03ce2fSLisandro Dalcin PetscFunctionBegin; 27507a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 27517a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 27527a03ce2fSLisandro Dalcin } 27537a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 27547a03ce2fSLisandro Dalcin } 27557a03ce2fSLisandro Dalcin 27569b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 27579b94acceSBarry Smith 27584a2ae208SSatish Balay #undef __FUNCT__ 2759a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 27609b94acceSBarry Smith /*@C 2761a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 27629b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 27639b94acceSBarry Smith progress. 27649b94acceSBarry Smith 27653f9fe445SBarry Smith Logically Collective on SNES 2766fee21e36SBarry Smith 2767c7afd0dbSLois Curfman McInnes Input Parameters: 2768c7afd0dbSLois Curfman McInnes + snes - the SNES context 2769c7afd0dbSLois Curfman McInnes . func - monitoring routine 2770b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 2771e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 2772b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 2773b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 27749b94acceSBarry Smith 2775c7afd0dbSLois Curfman McInnes Calling sequence of func: 2776a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2777c7afd0dbSLois Curfman McInnes 2778c7afd0dbSLois Curfman McInnes + snes - the SNES context 2779c7afd0dbSLois Curfman McInnes . its - iteration number 2780c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 278140a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 27829b94acceSBarry Smith 27839665c990SLois Curfman McInnes Options Database Keys: 2784a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 2785a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 2786a6570f20SBarry Smith uses SNESMonitorLGCreate() 2787cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 2788c7afd0dbSLois Curfman McInnes been hardwired into a code by 2789a6570f20SBarry Smith calls to SNESMonitorSet(), but 2790c7afd0dbSLois Curfman McInnes does not cancel those set via 2791c7afd0dbSLois Curfman McInnes the options database. 27929665c990SLois Curfman McInnes 2793639f9d9dSBarry Smith Notes: 27946bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 2795a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 27966bc08f3fSLois Curfman McInnes order in which they were set. 2797639f9d9dSBarry Smith 2798025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 2799025f1a04SBarry Smith 280036851e7fSLois Curfman McInnes Level: intermediate 280136851e7fSLois Curfman McInnes 28029b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 28039b94acceSBarry Smith 2804a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 28059b94acceSBarry Smith @*/ 2806c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 28079b94acceSBarry Smith { 2808b90d0a6eSBarry Smith PetscInt i; 2809649052a6SBarry Smith PetscErrorCode ierr; 2810b90d0a6eSBarry Smith 28113a40ed3dSBarry Smith PetscFunctionBegin; 28120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 281317186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2814b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 2815649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 2816649052a6SBarry Smith if (monitordestroy) { 2817c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 2818649052a6SBarry Smith } 2819b90d0a6eSBarry Smith PetscFunctionReturn(0); 2820b90d0a6eSBarry Smith } 2821b90d0a6eSBarry Smith } 2822b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 2823b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 2824639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 28253a40ed3dSBarry Smith PetscFunctionReturn(0); 28269b94acceSBarry Smith } 28279b94acceSBarry Smith 28284a2ae208SSatish Balay #undef __FUNCT__ 2829a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 28305cd90555SBarry Smith /*@C 2831a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 28325cd90555SBarry Smith 28333f9fe445SBarry Smith Logically Collective on SNES 2834c7afd0dbSLois Curfman McInnes 28355cd90555SBarry Smith Input Parameters: 28365cd90555SBarry Smith . snes - the SNES context 28375cd90555SBarry Smith 28381a480d89SAdministrator Options Database Key: 2839a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 2840a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 2841c7afd0dbSLois Curfman McInnes set via the options database 28425cd90555SBarry Smith 28435cd90555SBarry Smith Notes: 28445cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 28455cd90555SBarry Smith 284636851e7fSLois Curfman McInnes Level: intermediate 284736851e7fSLois Curfman McInnes 28485cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 28495cd90555SBarry Smith 2850a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 28515cd90555SBarry Smith @*/ 28527087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 28535cd90555SBarry Smith { 2854d952e501SBarry Smith PetscErrorCode ierr; 2855d952e501SBarry Smith PetscInt i; 2856d952e501SBarry Smith 28575cd90555SBarry Smith PetscFunctionBegin; 28580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2859d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 2860d952e501SBarry Smith if (snes->monitordestroy[i]) { 28613c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 2862d952e501SBarry Smith } 2863d952e501SBarry Smith } 28645cd90555SBarry Smith snes->numbermonitors = 0; 28655cd90555SBarry Smith PetscFunctionReturn(0); 28665cd90555SBarry Smith } 28675cd90555SBarry Smith 28684a2ae208SSatish Balay #undef __FUNCT__ 28694a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 28709b94acceSBarry Smith /*@C 28719b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 28729b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 28739b94acceSBarry Smith 28743f9fe445SBarry Smith Logically Collective on SNES 2875fee21e36SBarry Smith 2876c7afd0dbSLois Curfman McInnes Input Parameters: 2877c7afd0dbSLois Curfman McInnes + snes - the SNES context 2878c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 28797f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 28807f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 28819b94acceSBarry Smith 2882c7afd0dbSLois Curfman McInnes Calling sequence of func: 288306ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 2884c7afd0dbSLois Curfman McInnes 2885c7afd0dbSLois Curfman McInnes + snes - the SNES context 288606ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 2887c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 2888184914b5SBarry Smith . reason - reason for convergence/divergence 2889c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 28904b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 28914b27c08aSLois Curfman McInnes - f - 2-norm of function 28929b94acceSBarry Smith 289336851e7fSLois Curfman McInnes Level: advanced 289436851e7fSLois Curfman McInnes 28959b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 28969b94acceSBarry Smith 289785385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 28989b94acceSBarry Smith @*/ 28997087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 29009b94acceSBarry Smith { 29017f7931b9SBarry Smith PetscErrorCode ierr; 29027f7931b9SBarry Smith 29033a40ed3dSBarry Smith PetscFunctionBegin; 29040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 290585385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 29067f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 29077f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 29087f7931b9SBarry Smith } 290985385478SLisandro Dalcin snes->ops->converged = func; 29107f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 291185385478SLisandro Dalcin snes->cnvP = cctx; 29123a40ed3dSBarry Smith PetscFunctionReturn(0); 29139b94acceSBarry Smith } 29149b94acceSBarry Smith 29154a2ae208SSatish Balay #undef __FUNCT__ 29164a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 291752baeb72SSatish Balay /*@ 2918184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 2919184914b5SBarry Smith 2920184914b5SBarry Smith Not Collective 2921184914b5SBarry Smith 2922184914b5SBarry Smith Input Parameter: 2923184914b5SBarry Smith . snes - the SNES context 2924184914b5SBarry Smith 2925184914b5SBarry Smith Output Parameter: 29264d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 2927184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 2928184914b5SBarry Smith 2929184914b5SBarry Smith Level: intermediate 2930184914b5SBarry Smith 2931184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 2932184914b5SBarry Smith 2933184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 2934184914b5SBarry Smith 293585385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 2936184914b5SBarry Smith @*/ 29377087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 2938184914b5SBarry Smith { 2939184914b5SBarry Smith PetscFunctionBegin; 29400700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 29414482741eSBarry Smith PetscValidPointer(reason,2); 2942184914b5SBarry Smith *reason = snes->reason; 2943184914b5SBarry Smith PetscFunctionReturn(0); 2944184914b5SBarry Smith } 2945184914b5SBarry Smith 29464a2ae208SSatish Balay #undef __FUNCT__ 29474a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 2948c9005455SLois Curfman McInnes /*@ 2949c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 2950c9005455SLois Curfman McInnes 29513f9fe445SBarry Smith Logically Collective on SNES 2952fee21e36SBarry Smith 2953c7afd0dbSLois Curfman McInnes Input Parameters: 2954c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 29558c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 2956cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 2957758f92a0SBarry Smith . na - size of a and its 295864731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 2959758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 2960c7afd0dbSLois Curfman McInnes 2961308dcc3eSBarry Smith Notes: 2962308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 2963308dcc3eSBarry Smith default array of length 10000 is allocated. 2964308dcc3eSBarry Smith 2965c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 2966c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 2967c9005455SLois Curfman McInnes during the section of code that is being timed. 2968c9005455SLois Curfman McInnes 296936851e7fSLois Curfman McInnes Level: intermediate 297036851e7fSLois Curfman McInnes 2971c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 2972758f92a0SBarry Smith 297308405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 2974758f92a0SBarry Smith 2975c9005455SLois Curfman McInnes @*/ 29767087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 2977c9005455SLois Curfman McInnes { 2978308dcc3eSBarry Smith PetscErrorCode ierr; 2979308dcc3eSBarry Smith 29803a40ed3dSBarry Smith PetscFunctionBegin; 29810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 29824482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 2983a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 2984308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 2985308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 2986308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 2987308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 2988308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 2989308dcc3eSBarry Smith } 2990c9005455SLois Curfman McInnes snes->conv_hist = a; 2991758f92a0SBarry Smith snes->conv_hist_its = its; 2992758f92a0SBarry Smith snes->conv_hist_max = na; 2993a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 2994758f92a0SBarry Smith snes->conv_hist_reset = reset; 2995758f92a0SBarry Smith PetscFunctionReturn(0); 2996758f92a0SBarry Smith } 2997758f92a0SBarry Smith 2998308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 2999c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 3000c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 3001308dcc3eSBarry Smith EXTERN_C_BEGIN 3002308dcc3eSBarry Smith #undef __FUNCT__ 3003308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 3004308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3005308dcc3eSBarry Smith { 3006308dcc3eSBarry Smith mxArray *mat; 3007308dcc3eSBarry Smith PetscInt i; 3008308dcc3eSBarry Smith PetscReal *ar; 3009308dcc3eSBarry Smith 3010308dcc3eSBarry Smith PetscFunctionBegin; 3011308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3012308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3013308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 3014308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 3015308dcc3eSBarry Smith } 3016308dcc3eSBarry Smith PetscFunctionReturn(mat); 3017308dcc3eSBarry Smith } 3018308dcc3eSBarry Smith EXTERN_C_END 3019308dcc3eSBarry Smith #endif 3020308dcc3eSBarry Smith 3021308dcc3eSBarry Smith 30224a2ae208SSatish Balay #undef __FUNCT__ 30234a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 30240c4c9dddSBarry Smith /*@C 3025758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3026758f92a0SBarry Smith 30273f9fe445SBarry Smith Not Collective 3028758f92a0SBarry Smith 3029758f92a0SBarry Smith Input Parameter: 3030758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3031758f92a0SBarry Smith 3032758f92a0SBarry Smith Output Parameters: 3033758f92a0SBarry Smith . a - array to hold history 3034758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3035758f92a0SBarry Smith negative if not converged) for each solve. 3036758f92a0SBarry Smith - na - size of a and its 3037758f92a0SBarry Smith 3038758f92a0SBarry Smith Notes: 3039758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3040758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3041758f92a0SBarry Smith 3042758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3043758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3044758f92a0SBarry Smith during the section of code that is being timed. 3045758f92a0SBarry Smith 3046758f92a0SBarry Smith Level: intermediate 3047758f92a0SBarry Smith 3048758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3049758f92a0SBarry Smith 3050758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3051758f92a0SBarry Smith 3052758f92a0SBarry Smith @*/ 30537087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3054758f92a0SBarry Smith { 3055758f92a0SBarry Smith PetscFunctionBegin; 30560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3057758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3058758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3059758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 30603a40ed3dSBarry Smith PetscFunctionReturn(0); 3061c9005455SLois Curfman McInnes } 3062c9005455SLois Curfman McInnes 3063e74ef692SMatthew Knepley #undef __FUNCT__ 3064e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 3065ac226902SBarry Smith /*@C 306676b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3067eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 30687e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 306976b2cf59SMatthew Knepley 30703f9fe445SBarry Smith Logically Collective on SNES 307176b2cf59SMatthew Knepley 307276b2cf59SMatthew Knepley Input Parameters: 307376b2cf59SMatthew Knepley . snes - The nonlinear solver context 307476b2cf59SMatthew Knepley . func - The function 307576b2cf59SMatthew Knepley 307676b2cf59SMatthew Knepley Calling sequence of func: 3077b5d30489SBarry Smith . func (SNES snes, PetscInt step); 307876b2cf59SMatthew Knepley 307976b2cf59SMatthew Knepley . step - The current step of the iteration 308076b2cf59SMatthew Knepley 3081fe97e370SBarry Smith Level: advanced 3082fe97e370SBarry Smith 3083fe97e370SBarry 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() 3084fe97e370SBarry Smith This is not used by most users. 308576b2cf59SMatthew Knepley 308676b2cf59SMatthew Knepley .keywords: SNES, update 3087b5d30489SBarry Smith 308885385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 308976b2cf59SMatthew Knepley @*/ 30907087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 309176b2cf59SMatthew Knepley { 309276b2cf59SMatthew Knepley PetscFunctionBegin; 30930700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3094e7788613SBarry Smith snes->ops->update = func; 309576b2cf59SMatthew Knepley PetscFunctionReturn(0); 309676b2cf59SMatthew Knepley } 309776b2cf59SMatthew Knepley 3098e74ef692SMatthew Knepley #undef __FUNCT__ 3099e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 310076b2cf59SMatthew Knepley /*@ 310176b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 310276b2cf59SMatthew Knepley 310376b2cf59SMatthew Knepley Not collective 310476b2cf59SMatthew Knepley 310576b2cf59SMatthew Knepley Input Parameters: 310676b2cf59SMatthew Knepley . snes - The nonlinear solver context 310776b2cf59SMatthew Knepley . step - The current step of the iteration 310876b2cf59SMatthew Knepley 3109205452f4SMatthew Knepley Level: intermediate 3110205452f4SMatthew Knepley 311176b2cf59SMatthew Knepley .keywords: SNES, update 3112a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 311376b2cf59SMatthew Knepley @*/ 31147087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 311576b2cf59SMatthew Knepley { 311676b2cf59SMatthew Knepley PetscFunctionBegin; 311776b2cf59SMatthew Knepley PetscFunctionReturn(0); 311876b2cf59SMatthew Knepley } 311976b2cf59SMatthew Knepley 31204a2ae208SSatish Balay #undef __FUNCT__ 31214a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 31229b94acceSBarry Smith /* 31239b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 31249b94acceSBarry Smith positive parameter delta. 31259b94acceSBarry Smith 31269b94acceSBarry Smith Input Parameters: 3127c7afd0dbSLois Curfman McInnes + snes - the SNES context 31289b94acceSBarry Smith . y - approximate solution of linear system 31299b94acceSBarry Smith . fnorm - 2-norm of current function 3130c7afd0dbSLois Curfman McInnes - delta - trust region size 31319b94acceSBarry Smith 31329b94acceSBarry Smith Output Parameters: 3133c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 31349b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 31359b94acceSBarry Smith region, and exceeds zero otherwise. 3136c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 31379b94acceSBarry Smith 31389b94acceSBarry Smith Note: 31394b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 31409b94acceSBarry Smith is set to be the maximum allowable step size. 31419b94acceSBarry Smith 31429b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 31439b94acceSBarry Smith */ 3144dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 31459b94acceSBarry Smith { 3146064f8208SBarry Smith PetscReal nrm; 3147ea709b57SSatish Balay PetscScalar cnorm; 3148dfbe8321SBarry Smith PetscErrorCode ierr; 31493a40ed3dSBarry Smith 31503a40ed3dSBarry Smith PetscFunctionBegin; 31510700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31520700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3153c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3154184914b5SBarry Smith 3155064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3156064f8208SBarry Smith if (nrm > *delta) { 3157064f8208SBarry Smith nrm = *delta/nrm; 3158064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3159064f8208SBarry Smith cnorm = nrm; 31602dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 31619b94acceSBarry Smith *ynorm = *delta; 31629b94acceSBarry Smith } else { 31639b94acceSBarry Smith *gpnorm = 0.0; 3164064f8208SBarry Smith *ynorm = nrm; 31659b94acceSBarry Smith } 31663a40ed3dSBarry Smith PetscFunctionReturn(0); 31679b94acceSBarry Smith } 31689b94acceSBarry Smith 31694a2ae208SSatish Balay #undef __FUNCT__ 31704a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 31716ce558aeSBarry Smith /*@C 3172f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3173f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 31749b94acceSBarry Smith 3175c7afd0dbSLois Curfman McInnes Collective on SNES 3176c7afd0dbSLois Curfman McInnes 3177b2002411SLois Curfman McInnes Input Parameters: 3178c7afd0dbSLois Curfman McInnes + snes - the SNES context 31793cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 318085385478SLisandro Dalcin - x - the solution vector. 31819b94acceSBarry Smith 3182b2002411SLois Curfman McInnes Notes: 31838ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 31848ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 31858ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 31868ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 31878ddd3da0SLois Curfman McInnes 318836851e7fSLois Curfman McInnes Level: beginner 318936851e7fSLois Curfman McInnes 31909b94acceSBarry Smith .keywords: SNES, nonlinear, solve 31919b94acceSBarry Smith 3192c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 31939b94acceSBarry Smith @*/ 31947087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 31959b94acceSBarry Smith { 3196dfbe8321SBarry Smith PetscErrorCode ierr; 3197ace3abfcSBarry Smith PetscBool flg; 3198eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 3199eabae89aSBarry Smith PetscViewer viewer; 3200efd51863SBarry Smith PetscInt grid; 3201a69afd8bSBarry Smith Vec xcreated = PETSC_NULL; 3202052efed2SBarry Smith 32033a40ed3dSBarry Smith PetscFunctionBegin; 32040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3205a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3206a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 32070700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 320885385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 320985385478SLisandro Dalcin 3210a69afd8bSBarry Smith if (!x && snes->dm) { 3211a69afd8bSBarry Smith ierr = DMCreateGlobalVector(snes->dm,&xcreated);CHKERRQ(ierr); 3212a69afd8bSBarry Smith x = xcreated; 3213a69afd8bSBarry Smith } 3214a69afd8bSBarry Smith 3215a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3216efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3217efd51863SBarry Smith 321885385478SLisandro Dalcin /* set solution vector */ 3219efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 32206bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 322185385478SLisandro Dalcin snes->vec_sol = x; 322285385478SLisandro Dalcin /* set afine vector if provided */ 322385385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 32246bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 322585385478SLisandro Dalcin snes->vec_rhs = b; 322685385478SLisandro Dalcin 322770e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 32283f149594SLisandro Dalcin 32297eee914bSBarry Smith if (!grid) { 32307eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3231d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3232dd568438SSatish Balay } else if (snes->dm) { 3233dd568438SSatish Balay PetscBool ig; 3234dd568438SSatish Balay ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr); 3235dd568438SSatish Balay if (ig) { 32367eee914bSBarry Smith ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr); 32377eee914bSBarry Smith } 3238d25893d9SBarry Smith } 3239dd568438SSatish Balay } 3240d25893d9SBarry Smith 3241abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 324250ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3243d5e45103SBarry Smith 32443f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 32454936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 324685385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 32474936397dSBarry Smith if (snes->domainerror){ 32484936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 32494936397dSBarry Smith snes->domainerror = PETSC_FALSE; 32504936397dSBarry Smith } 325117186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 32523f149594SLisandro Dalcin 32537adad957SLisandro Dalcin ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 3254eabae89aSBarry Smith if (flg && !PetscPreLoadingOn) { 32557adad957SLisandro Dalcin ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 3256eabae89aSBarry Smith ierr = SNESView(snes,viewer);CHKERRQ(ierr); 32576bf464f9SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3258eabae89aSBarry Smith } 3259eabae89aSBarry Smith 326090d69ab7SBarry Smith flg = PETSC_FALSE; 3261acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3262da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 32635968eb51SBarry Smith if (snes->printreason) { 3264a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 32655968eb51SBarry Smith if (snes->reason > 0) { 3266c7e7b494SJed 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); 32675968eb51SBarry Smith } else { 3268c7e7b494SJed 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); 32695968eb51SBarry Smith } 3270a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 32715968eb51SBarry Smith } 32725968eb51SBarry Smith 32738501fc72SJed Brown flg = PETSC_FALSE; 32748501fc72SJed Brown ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 32758501fc72SJed Brown if (flg) { 32768501fc72SJed Brown PetscViewer viewer; 32778501fc72SJed Brown ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 32788501fc72SJed Brown ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 32798501fc72SJed Brown ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 32808501fc72SJed Brown ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 32818501fc72SJed Brown ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 32828501fc72SJed Brown } 32838501fc72SJed Brown 3284e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3285efd51863SBarry Smith if (grid < snes->gridsequence) { 3286efd51863SBarry Smith DM fine; 3287efd51863SBarry Smith Vec xnew; 3288efd51863SBarry Smith Mat interp; 3289efd51863SBarry Smith 3290efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3291e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3292efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3293efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3294efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3295efd51863SBarry Smith x = xnew; 3296efd51863SBarry Smith 3297efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3298efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3299efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3300a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3301efd51863SBarry Smith } 3302efd51863SBarry Smith } 3303a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 33043a40ed3dSBarry Smith PetscFunctionReturn(0); 33059b94acceSBarry Smith } 33069b94acceSBarry Smith 33079b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 33089b94acceSBarry Smith 33094a2ae208SSatish Balay #undef __FUNCT__ 33104a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 331182bf6240SBarry Smith /*@C 33124b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 33139b94acceSBarry Smith 3314fee21e36SBarry Smith Collective on SNES 3315fee21e36SBarry Smith 3316c7afd0dbSLois Curfman McInnes Input Parameters: 3317c7afd0dbSLois Curfman McInnes + snes - the SNES context 3318454a90a3SBarry Smith - type - a known method 3319c7afd0dbSLois Curfman McInnes 3320c7afd0dbSLois Curfman McInnes Options Database Key: 3321454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3322c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3323ae12b187SLois Curfman McInnes 33249b94acceSBarry Smith Notes: 3325e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 33264b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3327c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 33284b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3329c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 33309b94acceSBarry Smith 3331ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3332ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3333ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3334ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3335ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3336ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3337ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3338ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3339ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3340b0a32e0cSBarry Smith appropriate method. 334136851e7fSLois Curfman McInnes 334236851e7fSLois Curfman McInnes Level: intermediate 3343a703fe33SLois Curfman McInnes 3344454a90a3SBarry Smith .keywords: SNES, set, type 3345435da068SBarry Smith 3346435da068SBarry Smith .seealso: SNESType, SNESCreate() 3347435da068SBarry Smith 33489b94acceSBarry Smith @*/ 33497087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 33509b94acceSBarry Smith { 3351dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3352ace3abfcSBarry Smith PetscBool match; 33533a40ed3dSBarry Smith 33543a40ed3dSBarry Smith PetscFunctionBegin; 33550700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 33564482741eSBarry Smith PetscValidCharPointer(type,2); 335782bf6240SBarry Smith 33586831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 33590f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 336092ff6ae8SBarry Smith 33614b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3362e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 336375396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 3364b5c23020SJed Brown if (snes->ops->destroy) { 3365b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 3366b5c23020SJed Brown snes->ops->destroy = PETSC_NULL; 3367b5c23020SJed Brown } 336875396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 336975396ef9SLisandro Dalcin snes->ops->setup = 0; 337075396ef9SLisandro Dalcin snes->ops->solve = 0; 337175396ef9SLisandro Dalcin snes->ops->view = 0; 337275396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 337375396ef9SLisandro Dalcin snes->ops->destroy = 0; 337475396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 337575396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3376454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 337703bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 33789fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 33799fb22e1aSBarry Smith if (PetscAMSPublishAll) { 33809fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 33819fb22e1aSBarry Smith } 33829fb22e1aSBarry Smith #endif 33833a40ed3dSBarry Smith PetscFunctionReturn(0); 33849b94acceSBarry Smith } 33859b94acceSBarry Smith 3386a847f771SSatish Balay 33879b94acceSBarry Smith /* --------------------------------------------------------------------- */ 33884a2ae208SSatish Balay #undef __FUNCT__ 33894a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 339052baeb72SSatish Balay /*@ 33919b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3392f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 33939b94acceSBarry Smith 3394fee21e36SBarry Smith Not Collective 3395fee21e36SBarry Smith 339636851e7fSLois Curfman McInnes Level: advanced 339736851e7fSLois Curfman McInnes 33989b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 33999b94acceSBarry Smith 34009b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 34019b94acceSBarry Smith @*/ 34027087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 34039b94acceSBarry Smith { 3404dfbe8321SBarry Smith PetscErrorCode ierr; 340582bf6240SBarry Smith 34063a40ed3dSBarry Smith PetscFunctionBegin; 34071441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 34084c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 34093a40ed3dSBarry Smith PetscFunctionReturn(0); 34109b94acceSBarry Smith } 34119b94acceSBarry Smith 34124a2ae208SSatish Balay #undef __FUNCT__ 34134a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 34149b94acceSBarry Smith /*@C 34159a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 34169b94acceSBarry Smith 3417c7afd0dbSLois Curfman McInnes Not Collective 3418c7afd0dbSLois Curfman McInnes 34199b94acceSBarry Smith Input Parameter: 34204b0e389bSBarry Smith . snes - nonlinear solver context 34219b94acceSBarry Smith 34229b94acceSBarry Smith Output Parameter: 34233a7fca6bSBarry Smith . type - SNES method (a character string) 34249b94acceSBarry Smith 342536851e7fSLois Curfman McInnes Level: intermediate 342636851e7fSLois Curfman McInnes 3427454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 34289b94acceSBarry Smith @*/ 34297087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 34309b94acceSBarry Smith { 34313a40ed3dSBarry Smith PetscFunctionBegin; 34320700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34334482741eSBarry Smith PetscValidPointer(type,2); 34347adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 34353a40ed3dSBarry Smith PetscFunctionReturn(0); 34369b94acceSBarry Smith } 34379b94acceSBarry Smith 34384a2ae208SSatish Balay #undef __FUNCT__ 34394a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 344052baeb72SSatish Balay /*@ 34419b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3442c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 34439b94acceSBarry Smith 3444c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3445c7afd0dbSLois Curfman McInnes 34469b94acceSBarry Smith Input Parameter: 34479b94acceSBarry Smith . snes - the SNES context 34489b94acceSBarry Smith 34499b94acceSBarry Smith Output Parameter: 34509b94acceSBarry Smith . x - the solution 34519b94acceSBarry Smith 345270e92668SMatthew Knepley Level: intermediate 345336851e7fSLois Curfman McInnes 34549b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 34559b94acceSBarry Smith 345685385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 34579b94acceSBarry Smith @*/ 34587087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 34599b94acceSBarry Smith { 34603a40ed3dSBarry Smith PetscFunctionBegin; 34610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34624482741eSBarry Smith PetscValidPointer(x,2); 346385385478SLisandro Dalcin *x = snes->vec_sol; 346470e92668SMatthew Knepley PetscFunctionReturn(0); 346570e92668SMatthew Knepley } 346670e92668SMatthew Knepley 346770e92668SMatthew Knepley #undef __FUNCT__ 34684a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 346952baeb72SSatish Balay /*@ 34709b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 34719b94acceSBarry Smith stored. 34729b94acceSBarry Smith 3473c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3474c7afd0dbSLois Curfman McInnes 34759b94acceSBarry Smith Input Parameter: 34769b94acceSBarry Smith . snes - the SNES context 34779b94acceSBarry Smith 34789b94acceSBarry Smith Output Parameter: 34799b94acceSBarry Smith . x - the solution update 34809b94acceSBarry Smith 348136851e7fSLois Curfman McInnes Level: advanced 348236851e7fSLois Curfman McInnes 34839b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 34849b94acceSBarry Smith 348585385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 34869b94acceSBarry Smith @*/ 34877087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 34889b94acceSBarry Smith { 34893a40ed3dSBarry Smith PetscFunctionBegin; 34900700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34914482741eSBarry Smith PetscValidPointer(x,2); 349285385478SLisandro Dalcin *x = snes->vec_sol_update; 34933a40ed3dSBarry Smith PetscFunctionReturn(0); 34949b94acceSBarry Smith } 34959b94acceSBarry Smith 34964a2ae208SSatish Balay #undef __FUNCT__ 34974a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 34989b94acceSBarry Smith /*@C 34993638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 35009b94acceSBarry Smith 3501a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 3502c7afd0dbSLois Curfman McInnes 35039b94acceSBarry Smith Input Parameter: 35049b94acceSBarry Smith . snes - the SNES context 35059b94acceSBarry Smith 35069b94acceSBarry Smith Output Parameter: 35077bf4e008SBarry Smith + r - the function (or PETSC_NULL) 350870e92668SMatthew Knepley . func - the function (or PETSC_NULL) 350970e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 35109b94acceSBarry Smith 351136851e7fSLois Curfman McInnes Level: advanced 351236851e7fSLois Curfman McInnes 3513a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 35149b94acceSBarry Smith 35154b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 35169b94acceSBarry Smith @*/ 35177087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 35189b94acceSBarry Smith { 3519a63bb30eSJed Brown PetscErrorCode ierr; 35206cab3a1bSJed Brown DM dm; 3521a63bb30eSJed Brown 35223a40ed3dSBarry Smith PetscFunctionBegin; 35230700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3524a63bb30eSJed Brown if (r) { 3525a63bb30eSJed Brown if (!snes->vec_func) { 3526a63bb30eSJed Brown if (snes->vec_rhs) { 3527a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 3528a63bb30eSJed Brown } else if (snes->vec_sol) { 3529a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 3530a63bb30eSJed Brown } else if (snes->dm) { 3531a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 3532a63bb30eSJed Brown } 3533a63bb30eSJed Brown } 3534a63bb30eSJed Brown *r = snes->vec_func; 3535a63bb30eSJed Brown } 35366cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 35376cab3a1bSJed Brown ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr); 35383a40ed3dSBarry Smith PetscFunctionReturn(0); 35399b94acceSBarry Smith } 35409b94acceSBarry Smith 3541c79ef259SPeter Brune /*@C 3542c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3543c79ef259SPeter Brune 3544c79ef259SPeter Brune Input Parameter: 3545c79ef259SPeter Brune . snes - the SNES context 3546c79ef259SPeter Brune 3547c79ef259SPeter Brune Output Parameter: 3548c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3549c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3550c79ef259SPeter Brune 3551c79ef259SPeter Brune Level: advanced 3552c79ef259SPeter Brune 3553c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3554c79ef259SPeter Brune 3555c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3556c79ef259SPeter Brune @*/ 3557c79ef259SPeter Brune 35584a2ae208SSatish Balay #undef __FUNCT__ 3559646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3560646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3561646217ecSPeter Brune { 35626cab3a1bSJed Brown PetscErrorCode ierr; 35636cab3a1bSJed Brown DM dm; 35646cab3a1bSJed Brown 3565646217ecSPeter Brune PetscFunctionBegin; 3566646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35676cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 35686cab3a1bSJed Brown ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr); 3569646217ecSPeter Brune PetscFunctionReturn(0); 3570646217ecSPeter Brune } 3571646217ecSPeter Brune 35724a2ae208SSatish Balay #undef __FUNCT__ 35734a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 35743c7409f5SSatish Balay /*@C 35753c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3576d850072dSLois Curfman McInnes SNES options in the database. 35773c7409f5SSatish Balay 35783f9fe445SBarry Smith Logically Collective on SNES 3579fee21e36SBarry Smith 3580c7afd0dbSLois Curfman McInnes Input Parameter: 3581c7afd0dbSLois Curfman McInnes + snes - the SNES context 3582c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3583c7afd0dbSLois Curfman McInnes 3584d850072dSLois Curfman McInnes Notes: 3585a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3586c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3587d850072dSLois Curfman McInnes 358836851e7fSLois Curfman McInnes Level: advanced 358936851e7fSLois Curfman McInnes 35903c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3591a86d99e1SLois Curfman McInnes 3592a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 35933c7409f5SSatish Balay @*/ 35947087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 35953c7409f5SSatish Balay { 3596dfbe8321SBarry Smith PetscErrorCode ierr; 35973c7409f5SSatish Balay 35983a40ed3dSBarry Smith PetscFunctionBegin; 35990700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3600639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 36011cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 360294b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 36033a40ed3dSBarry Smith PetscFunctionReturn(0); 36043c7409f5SSatish Balay } 36053c7409f5SSatish Balay 36064a2ae208SSatish Balay #undef __FUNCT__ 36074a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 36083c7409f5SSatish Balay /*@C 3609f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to 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 Parameters: 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, append, options, prefix, database 3625a86d99e1SLois Curfman McInnes 3626a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 36273c7409f5SSatish Balay @*/ 36287087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(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 = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 36351cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 363694b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 36373a40ed3dSBarry Smith PetscFunctionReturn(0); 36383c7409f5SSatish Balay } 36393c7409f5SSatish Balay 36404a2ae208SSatish Balay #undef __FUNCT__ 36414a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 36429ab63eb5SSatish Balay /*@C 36433c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 36443c7409f5SSatish Balay SNES options in the database. 36453c7409f5SSatish Balay 3646c7afd0dbSLois Curfman McInnes Not Collective 3647c7afd0dbSLois Curfman McInnes 36483c7409f5SSatish Balay Input Parameter: 36493c7409f5SSatish Balay . snes - the SNES context 36503c7409f5SSatish Balay 36513c7409f5SSatish Balay Output Parameter: 36523c7409f5SSatish Balay . prefix - pointer to the prefix string used 36533c7409f5SSatish Balay 36544ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 36559ab63eb5SSatish Balay sufficient length to hold the prefix. 36569ab63eb5SSatish Balay 365736851e7fSLois Curfman McInnes Level: advanced 365836851e7fSLois Curfman McInnes 36593c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 3660a86d99e1SLois Curfman McInnes 3661a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 36623c7409f5SSatish Balay @*/ 36637087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 36643c7409f5SSatish Balay { 3665dfbe8321SBarry Smith PetscErrorCode ierr; 36663c7409f5SSatish Balay 36673a40ed3dSBarry Smith PetscFunctionBegin; 36680700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3669639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 36703a40ed3dSBarry Smith PetscFunctionReturn(0); 36713c7409f5SSatish Balay } 36723c7409f5SSatish Balay 3673b2002411SLois Curfman McInnes 36744a2ae208SSatish Balay #undef __FUNCT__ 36754a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 36763cea93caSBarry Smith /*@C 36773cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 36783cea93caSBarry Smith 36797f6c08e0SMatthew Knepley Level: advanced 36803cea93caSBarry Smith @*/ 36817087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3682b2002411SLois Curfman McInnes { 3683e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3684dfbe8321SBarry Smith PetscErrorCode ierr; 3685b2002411SLois Curfman McInnes 3686b2002411SLois Curfman McInnes PetscFunctionBegin; 3687b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3688c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3689b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3690b2002411SLois Curfman McInnes } 3691da9b6338SBarry Smith 3692da9b6338SBarry Smith #undef __FUNCT__ 3693da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 36947087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3695da9b6338SBarry Smith { 3696dfbe8321SBarry Smith PetscErrorCode ierr; 369777431f27SBarry Smith PetscInt N,i,j; 3698da9b6338SBarry Smith Vec u,uh,fh; 3699da9b6338SBarry Smith PetscScalar value; 3700da9b6338SBarry Smith PetscReal norm; 3701da9b6338SBarry Smith 3702da9b6338SBarry Smith PetscFunctionBegin; 3703da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3704da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3705da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3706da9b6338SBarry Smith 3707da9b6338SBarry Smith /* currently only works for sequential */ 3708da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3709da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3710da9b6338SBarry Smith for (i=0; i<N; i++) { 3711da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 371277431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3713da9b6338SBarry Smith for (j=-10; j<11; j++) { 3714ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3715da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 37163ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3717da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 371877431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3719da9b6338SBarry Smith value = -value; 3720da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3721da9b6338SBarry Smith } 3722da9b6338SBarry Smith } 37236bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 37246bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 3725da9b6338SBarry Smith PetscFunctionReturn(0); 3726da9b6338SBarry Smith } 372771f87433Sdalcinl 372871f87433Sdalcinl #undef __FUNCT__ 3729fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 373071f87433Sdalcinl /*@ 3731fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 373271f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 373371f87433Sdalcinl Newton method. 373471f87433Sdalcinl 37353f9fe445SBarry Smith Logically Collective on SNES 373671f87433Sdalcinl 373771f87433Sdalcinl Input Parameters: 373871f87433Sdalcinl + snes - SNES context 373971f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 374071f87433Sdalcinl 374164ba62caSBarry Smith Options Database: 374264ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 374364ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 374464ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 374564ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 374664ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 374764ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 374864ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 374964ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 375064ba62caSBarry Smith 375171f87433Sdalcinl Notes: 375271f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 375371f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 375471f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 375571f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 375671f87433Sdalcinl solver. 375771f87433Sdalcinl 375871f87433Sdalcinl Level: advanced 375971f87433Sdalcinl 376071f87433Sdalcinl Reference: 376171f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 376271f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 376371f87433Sdalcinl 376471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 376571f87433Sdalcinl 3766fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 376771f87433Sdalcinl @*/ 37687087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 376971f87433Sdalcinl { 377071f87433Sdalcinl PetscFunctionBegin; 37710700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3772acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 377371f87433Sdalcinl snes->ksp_ewconv = flag; 377471f87433Sdalcinl PetscFunctionReturn(0); 377571f87433Sdalcinl } 377671f87433Sdalcinl 377771f87433Sdalcinl #undef __FUNCT__ 3778fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 377971f87433Sdalcinl /*@ 3780fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 378171f87433Sdalcinl for computing relative tolerance for linear solvers within an 378271f87433Sdalcinl inexact Newton method. 378371f87433Sdalcinl 378471f87433Sdalcinl Not Collective 378571f87433Sdalcinl 378671f87433Sdalcinl Input Parameter: 378771f87433Sdalcinl . snes - SNES context 378871f87433Sdalcinl 378971f87433Sdalcinl Output Parameter: 379071f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 379171f87433Sdalcinl 379271f87433Sdalcinl Notes: 379371f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 379471f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 379571f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 379671f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 379771f87433Sdalcinl solver. 379871f87433Sdalcinl 379971f87433Sdalcinl Level: advanced 380071f87433Sdalcinl 380171f87433Sdalcinl Reference: 380271f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 380371f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 380471f87433Sdalcinl 380571f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 380671f87433Sdalcinl 3807fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 380871f87433Sdalcinl @*/ 38097087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 381071f87433Sdalcinl { 381171f87433Sdalcinl PetscFunctionBegin; 38120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 381371f87433Sdalcinl PetscValidPointer(flag,2); 381471f87433Sdalcinl *flag = snes->ksp_ewconv; 381571f87433Sdalcinl PetscFunctionReturn(0); 381671f87433Sdalcinl } 381771f87433Sdalcinl 381871f87433Sdalcinl #undef __FUNCT__ 3819fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 382071f87433Sdalcinl /*@ 3821fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 382271f87433Sdalcinl convergence criteria for the linear solvers within an inexact 382371f87433Sdalcinl Newton method. 382471f87433Sdalcinl 38253f9fe445SBarry Smith Logically Collective on SNES 382671f87433Sdalcinl 382771f87433Sdalcinl Input Parameters: 382871f87433Sdalcinl + snes - SNES context 382971f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 383071f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 383171f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 383271f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 383371f87433Sdalcinl (0 <= gamma2 <= 1) 383471f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 383571f87433Sdalcinl . alpha2 - power for safeguard 383671f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 383771f87433Sdalcinl 383871f87433Sdalcinl Note: 383971f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 384071f87433Sdalcinl 384171f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 384271f87433Sdalcinl 384371f87433Sdalcinl Level: advanced 384471f87433Sdalcinl 384571f87433Sdalcinl Reference: 384671f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 384771f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 384871f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 384971f87433Sdalcinl 385071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 385171f87433Sdalcinl 3852fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 385371f87433Sdalcinl @*/ 38547087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 385571f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 385671f87433Sdalcinl { 3857fa9f3622SBarry Smith SNESKSPEW *kctx; 385871f87433Sdalcinl PetscFunctionBegin; 38590700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3860fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3861e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 3862c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 3863c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 3864c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 3865c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 3866c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 3867c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 3868c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 386971f87433Sdalcinl 387071f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 387171f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 387271f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 387371f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 387471f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 387571f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 387671f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 387771f87433Sdalcinl 387871f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 3879e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 388071f87433Sdalcinl } 388171f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 3882e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 388371f87433Sdalcinl } 388471f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 3885e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 388671f87433Sdalcinl } 388771f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 3888e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 388971f87433Sdalcinl } 389071f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 3891e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 389271f87433Sdalcinl } 389371f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 3894e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 389571f87433Sdalcinl } 389671f87433Sdalcinl PetscFunctionReturn(0); 389771f87433Sdalcinl } 389871f87433Sdalcinl 389971f87433Sdalcinl #undef __FUNCT__ 3900fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 390171f87433Sdalcinl /*@ 3902fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 390371f87433Sdalcinl convergence criteria for the linear solvers within an inexact 390471f87433Sdalcinl Newton method. 390571f87433Sdalcinl 390671f87433Sdalcinl Not Collective 390771f87433Sdalcinl 390871f87433Sdalcinl Input Parameters: 390971f87433Sdalcinl snes - SNES context 391071f87433Sdalcinl 391171f87433Sdalcinl Output Parameters: 391271f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 391371f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 391471f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 391571f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 391671f87433Sdalcinl (0 <= gamma2 <= 1) 391771f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 391871f87433Sdalcinl . alpha2 - power for safeguard 391971f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 392071f87433Sdalcinl 392171f87433Sdalcinl Level: advanced 392271f87433Sdalcinl 392371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 392471f87433Sdalcinl 3925fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 392671f87433Sdalcinl @*/ 39277087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 392871f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 392971f87433Sdalcinl { 3930fa9f3622SBarry Smith SNESKSPEW *kctx; 393171f87433Sdalcinl PetscFunctionBegin; 39320700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3933fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3934e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 393571f87433Sdalcinl if(version) *version = kctx->version; 393671f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 393771f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 393871f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 393971f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 394071f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 394171f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 394271f87433Sdalcinl PetscFunctionReturn(0); 394371f87433Sdalcinl } 394471f87433Sdalcinl 394571f87433Sdalcinl #undef __FUNCT__ 3946fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 3947fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 394871f87433Sdalcinl { 394971f87433Sdalcinl PetscErrorCode ierr; 3950fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 395171f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 395271f87433Sdalcinl 395371f87433Sdalcinl PetscFunctionBegin; 3954e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 395571f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 395671f87433Sdalcinl rtol = kctx->rtol_0; 395771f87433Sdalcinl } else { 395871f87433Sdalcinl if (kctx->version == 1) { 395971f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 396071f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 396171f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 396271f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 396371f87433Sdalcinl } else if (kctx->version == 2) { 396471f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 396571f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 396671f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 396771f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 396871f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 396971f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 397071f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 397171f87433Sdalcinl stol = PetscMax(rtol,stol); 397271f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 397371f87433Sdalcinl /* safeguard: avoid oversolving */ 397471f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 397571f87433Sdalcinl stol = PetscMax(rtol,stol); 397671f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 3977e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 397871f87433Sdalcinl } 397971f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 398071f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 398171f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 398271f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 398371f87433Sdalcinl PetscFunctionReturn(0); 398471f87433Sdalcinl } 398571f87433Sdalcinl 398671f87433Sdalcinl #undef __FUNCT__ 3987fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 3988fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 398971f87433Sdalcinl { 399071f87433Sdalcinl PetscErrorCode ierr; 3991fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 399271f87433Sdalcinl PCSide pcside; 399371f87433Sdalcinl Vec lres; 399471f87433Sdalcinl 399571f87433Sdalcinl PetscFunctionBegin; 3996e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 399771f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 399871f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 399971f87433Sdalcinl if (kctx->version == 1) { 4000b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 400171f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 400271f87433Sdalcinl /* KSP residual is true linear residual */ 400371f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 400471f87433Sdalcinl } else { 400571f87433Sdalcinl /* KSP residual is preconditioned residual */ 400671f87433Sdalcinl /* compute true linear residual norm */ 400771f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 400871f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 400971f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 401071f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 40116bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 401271f87433Sdalcinl } 401371f87433Sdalcinl } 401471f87433Sdalcinl PetscFunctionReturn(0); 401571f87433Sdalcinl } 401671f87433Sdalcinl 401771f87433Sdalcinl #undef __FUNCT__ 401871f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 401971f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 402071f87433Sdalcinl { 402171f87433Sdalcinl PetscErrorCode ierr; 402271f87433Sdalcinl 402371f87433Sdalcinl PetscFunctionBegin; 4024fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 402571f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 4026fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 402771f87433Sdalcinl PetscFunctionReturn(0); 402871f87433Sdalcinl } 40296c699258SBarry Smith 40306c699258SBarry Smith #undef __FUNCT__ 40316c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 40326c699258SBarry Smith /*@ 40336c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 40346c699258SBarry Smith 40353f9fe445SBarry Smith Logically Collective on SNES 40366c699258SBarry Smith 40376c699258SBarry Smith Input Parameters: 40386c699258SBarry Smith + snes - the preconditioner context 40396c699258SBarry Smith - dm - the dm 40406c699258SBarry Smith 40416c699258SBarry Smith Level: intermediate 40426c699258SBarry Smith 40436c699258SBarry Smith 40446c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 40456c699258SBarry Smith @*/ 40467087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 40476c699258SBarry Smith { 40486c699258SBarry Smith PetscErrorCode ierr; 4049345fed2cSBarry Smith KSP ksp; 40506cab3a1bSJed Brown SNESDM sdm; 40516c699258SBarry Smith 40526c699258SBarry Smith PetscFunctionBegin; 40530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4054d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 40556cab3a1bSJed Brown if (snes->dm) { /* Move the SNESDM context over to the new DM unless the new DM already has one */ 40566cab3a1bSJed Brown PetscContainer oldcontainer,container; 40576cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 40586cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr); 40596cab3a1bSJed Brown if (oldcontainer && !container) { 40606cab3a1bSJed Brown ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr); 40616cab3a1bSJed Brown ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr); 40626cab3a1bSJed Brown if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */ 40636cab3a1bSJed Brown sdm->originaldm = dm; 40646cab3a1bSJed Brown } 40656cab3a1bSJed Brown } 40666bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 40676cab3a1bSJed Brown } 40686c699258SBarry Smith snes->dm = dm; 4069345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4070345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4071f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 40722c155ee1SBarry Smith if (snes->pc) { 40732c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 40742c155ee1SBarry Smith } 40756c699258SBarry Smith PetscFunctionReturn(0); 40766c699258SBarry Smith } 40776c699258SBarry Smith 40786c699258SBarry Smith #undef __FUNCT__ 40796c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 40806c699258SBarry Smith /*@ 40816c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 40826c699258SBarry Smith 40833f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 40846c699258SBarry Smith 40856c699258SBarry Smith Input Parameter: 40866c699258SBarry Smith . snes - the preconditioner context 40876c699258SBarry Smith 40886c699258SBarry Smith Output Parameter: 40896c699258SBarry Smith . dm - the dm 40906c699258SBarry Smith 40916c699258SBarry Smith Level: intermediate 40926c699258SBarry Smith 40936c699258SBarry Smith 40946c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 40956c699258SBarry Smith @*/ 40967087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 40976c699258SBarry Smith { 40986cab3a1bSJed Brown PetscErrorCode ierr; 40996cab3a1bSJed Brown 41006c699258SBarry Smith PetscFunctionBegin; 41010700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 41026cab3a1bSJed Brown if (!snes->dm) { 41036cab3a1bSJed Brown ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr); 41046cab3a1bSJed Brown } 41056c699258SBarry Smith *dm = snes->dm; 41066c699258SBarry Smith PetscFunctionReturn(0); 41076c699258SBarry Smith } 41080807856dSBarry Smith 410931823bd8SMatthew G Knepley #undef __FUNCT__ 411031823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 411131823bd8SMatthew G Knepley /*@ 4112fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 411331823bd8SMatthew G Knepley 411431823bd8SMatthew G Knepley Collective on SNES 411531823bd8SMatthew G Knepley 411631823bd8SMatthew G Knepley Input Parameters: 411731823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 411831823bd8SMatthew G Knepley - pc - the preconditioner object 411931823bd8SMatthew G Knepley 412031823bd8SMatthew G Knepley Notes: 412131823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 412231823bd8SMatthew G Knepley to configure it using the API). 412331823bd8SMatthew G Knepley 412431823bd8SMatthew G Knepley Level: developer 412531823bd8SMatthew G Knepley 412631823bd8SMatthew G Knepley .keywords: SNES, set, precondition 412731823bd8SMatthew G Knepley .seealso: SNESGetPC() 412831823bd8SMatthew G Knepley @*/ 412931823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 413031823bd8SMatthew G Knepley { 413131823bd8SMatthew G Knepley PetscErrorCode ierr; 413231823bd8SMatthew G Knepley 413331823bd8SMatthew G Knepley PetscFunctionBegin; 413431823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 413531823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 413631823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 413731823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4138bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 413931823bd8SMatthew G Knepley snes->pc = pc; 414031823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 414131823bd8SMatthew G Knepley PetscFunctionReturn(0); 414231823bd8SMatthew G Knepley } 414331823bd8SMatthew G Knepley 414431823bd8SMatthew G Knepley #undef __FUNCT__ 414531823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 414631823bd8SMatthew G Knepley /*@ 4147fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 414831823bd8SMatthew G Knepley 414931823bd8SMatthew G Knepley Not Collective 415031823bd8SMatthew G Knepley 415131823bd8SMatthew G Knepley Input Parameter: 415231823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 415331823bd8SMatthew G Knepley 415431823bd8SMatthew G Knepley Output Parameter: 415531823bd8SMatthew G Knepley . pc - preconditioner context 415631823bd8SMatthew G Knepley 415731823bd8SMatthew G Knepley Level: developer 415831823bd8SMatthew G Knepley 415931823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 416031823bd8SMatthew G Knepley .seealso: SNESSetPC() 416131823bd8SMatthew G Knepley @*/ 416231823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 416331823bd8SMatthew G Knepley { 416431823bd8SMatthew G Knepley PetscErrorCode ierr; 416531823bd8SMatthew G Knepley 416631823bd8SMatthew G Knepley PetscFunctionBegin; 416731823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 416831823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 416931823bd8SMatthew G Knepley if (!snes->pc) { 417031823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr); 41714a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr); 417231823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 417331823bd8SMatthew G Knepley } 417431823bd8SMatthew G Knepley *pc = snes->pc; 417531823bd8SMatthew G Knepley PetscFunctionReturn(0); 417631823bd8SMatthew G Knepley } 417731823bd8SMatthew G Knepley 41789e764e56SPeter Brune #undef __FUNCT__ 41799e764e56SPeter Brune #define __FUNCT__ "SNESSetPetscLineSearch" 41809e764e56SPeter Brune /*@ 41819e764e56SPeter Brune SNESSetPetscLineSearch - Sets the linesearch. 41829e764e56SPeter Brune 41839e764e56SPeter Brune Collective on SNES 41849e764e56SPeter Brune 41859e764e56SPeter Brune Input Parameters: 41869e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 41879e764e56SPeter Brune - linesearch - the linesearch object 41889e764e56SPeter Brune 41899e764e56SPeter Brune Notes: 41909e764e56SPeter Brune Use SNESGetPetscLineSearch() to retrieve the preconditioner context (for example, 41919e764e56SPeter Brune to configure it using the API). 41929e764e56SPeter Brune 41939e764e56SPeter Brune Level: developer 41949e764e56SPeter Brune 41959e764e56SPeter Brune .keywords: SNES, set, linesearch 4196ea5d4fccSPeter Brune .seealso: SNESGetPetscLineSearch() 41979e764e56SPeter Brune @*/ 41989e764e56SPeter Brune PetscErrorCode SNESSetPetscLineSearch(SNES snes, PetscLineSearch linesearch) 41999e764e56SPeter Brune { 42009e764e56SPeter Brune PetscErrorCode ierr; 42019e764e56SPeter Brune 42029e764e56SPeter Brune PetscFunctionBegin; 42039e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 42049e764e56SPeter Brune PetscValidHeaderSpecific(linesearch, PETSCLINESEARCH_CLASSID, 2); 42059e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 42069e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 42079e764e56SPeter Brune ierr = PetscLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 42089e764e56SPeter Brune snes->linesearch = linesearch; 42099e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 42109e764e56SPeter Brune PetscFunctionReturn(0); 42119e764e56SPeter Brune } 42129e764e56SPeter Brune 42139e764e56SPeter Brune #undef __FUNCT__ 42149e764e56SPeter Brune #define __FUNCT__ "SNESGetPetscLineSearch" 4215ea5d4fccSPeter Brune /*@C 42169e764e56SPeter Brune SNESGetPetscLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch(). 42179e764e56SPeter Brune 42189e764e56SPeter Brune Not Collective 42199e764e56SPeter Brune 42209e764e56SPeter Brune Input Parameter: 42219e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 42229e764e56SPeter Brune 42239e764e56SPeter Brune Output Parameter: 42249e764e56SPeter Brune . linesearch - linesearch context 42259e764e56SPeter Brune 42269e764e56SPeter Brune Level: developer 42279e764e56SPeter Brune 42289e764e56SPeter Brune .keywords: SNES, get, linesearch 42299e764e56SPeter Brune .seealso: SNESSetPetscLineSearch() 42309e764e56SPeter Brune @*/ 42319e764e56SPeter Brune PetscErrorCode SNESGetPetscLineSearch(SNES snes, PetscLineSearch *linesearch) 42329e764e56SPeter Brune { 42339e764e56SPeter Brune PetscErrorCode ierr; 42349e764e56SPeter Brune const char *optionsprefix; 42359e764e56SPeter Brune 42369e764e56SPeter Brune PetscFunctionBegin; 42379e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 42389e764e56SPeter Brune PetscValidPointer(linesearch, 2); 42399e764e56SPeter Brune if (!snes->linesearch) { 42409e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 42419e764e56SPeter Brune ierr = PetscLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr); 42429e764e56SPeter Brune ierr = PetscLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 42439e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 42449e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 42459e764e56SPeter Brune } 42469e764e56SPeter Brune *linesearch = snes->linesearch; 42479e764e56SPeter Brune PetscFunctionReturn(0); 42489e764e56SPeter Brune } 42499e764e56SPeter Brune 425069b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4251c6db04a5SJed Brown #include <mex.h> 425269b4f73cSBarry Smith 42538f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 42548f6e6473SBarry Smith 42550807856dSBarry Smith #undef __FUNCT__ 42560807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 42570807856dSBarry Smith /* 42580807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 42590807856dSBarry Smith SNESSetFunctionMatlab(). 42600807856dSBarry Smith 42610807856dSBarry Smith Collective on SNES 42620807856dSBarry Smith 42630807856dSBarry Smith Input Parameters: 42640807856dSBarry Smith + snes - the SNES context 42650807856dSBarry Smith - x - input vector 42660807856dSBarry Smith 42670807856dSBarry Smith Output Parameter: 42680807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 42690807856dSBarry Smith 42700807856dSBarry Smith Notes: 42710807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 42720807856dSBarry Smith implementations, so most users would not generally call this routine 42730807856dSBarry Smith themselves. 42740807856dSBarry Smith 42750807856dSBarry Smith Level: developer 42760807856dSBarry Smith 42770807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 42780807856dSBarry Smith 42790807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 428061b2408cSBarry Smith */ 42817087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 42820807856dSBarry Smith { 4283e650e774SBarry Smith PetscErrorCode ierr; 42848f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 42858f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 42868f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 428791621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 4288e650e774SBarry Smith 42890807856dSBarry Smith PetscFunctionBegin; 42900807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 42910807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 42920807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 42930807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 42940807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 42950807856dSBarry Smith 42960807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 4297e650e774SBarry Smith 429891621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4299e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4300e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 430191621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 430291621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 430391621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 43048f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 43058f6e6473SBarry Smith prhs[4] = sctx->ctx; 4306b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 4307e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4308e650e774SBarry Smith mxDestroyArray(prhs[0]); 4309e650e774SBarry Smith mxDestroyArray(prhs[1]); 4310e650e774SBarry Smith mxDestroyArray(prhs[2]); 43118f6e6473SBarry Smith mxDestroyArray(prhs[3]); 4312e650e774SBarry Smith mxDestroyArray(plhs[0]); 43130807856dSBarry Smith PetscFunctionReturn(0); 43140807856dSBarry Smith } 43150807856dSBarry Smith 43160807856dSBarry Smith 43170807856dSBarry Smith #undef __FUNCT__ 43180807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 431961b2408cSBarry Smith /* 43200807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 43210807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4322e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 43230807856dSBarry Smith 43240807856dSBarry Smith Logically Collective on SNES 43250807856dSBarry Smith 43260807856dSBarry Smith Input Parameters: 43270807856dSBarry Smith + snes - the SNES context 43280807856dSBarry Smith . r - vector to store function value 43290807856dSBarry Smith - func - function evaluation routine 43300807856dSBarry Smith 43310807856dSBarry Smith Calling sequence of func: 433261b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 43330807856dSBarry Smith 43340807856dSBarry Smith 43350807856dSBarry Smith Notes: 43360807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 43370807856dSBarry Smith $ f'(x) x = -f(x), 43380807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 43390807856dSBarry Smith 43400807856dSBarry Smith Level: beginner 43410807856dSBarry Smith 43420807856dSBarry Smith .keywords: SNES, nonlinear, set, function 43430807856dSBarry Smith 43440807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 434561b2408cSBarry Smith */ 43467087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 43470807856dSBarry Smith { 43480807856dSBarry Smith PetscErrorCode ierr; 43498f6e6473SBarry Smith SNESMatlabContext *sctx; 43500807856dSBarry Smith 43510807856dSBarry Smith PetscFunctionBegin; 43528f6e6473SBarry Smith /* currently sctx is memory bleed */ 43538f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 43548f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 43558f6e6473SBarry Smith /* 43568f6e6473SBarry Smith This should work, but it doesn't 43578f6e6473SBarry Smith sctx->ctx = ctx; 43588f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 43598f6e6473SBarry Smith */ 43608f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 43618f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 43620807856dSBarry Smith PetscFunctionReturn(0); 43630807856dSBarry Smith } 436469b4f73cSBarry Smith 436561b2408cSBarry Smith #undef __FUNCT__ 436661b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 436761b2408cSBarry Smith /* 436861b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 436961b2408cSBarry Smith SNESSetJacobianMatlab(). 437061b2408cSBarry Smith 437161b2408cSBarry Smith Collective on SNES 437261b2408cSBarry Smith 437361b2408cSBarry Smith Input Parameters: 437461b2408cSBarry Smith + snes - the SNES context 437561b2408cSBarry Smith . x - input vector 437661b2408cSBarry Smith . A, B - the matrices 437761b2408cSBarry Smith - ctx - user context 437861b2408cSBarry Smith 437961b2408cSBarry Smith Output Parameter: 438061b2408cSBarry Smith . flag - structure of the matrix 438161b2408cSBarry Smith 438261b2408cSBarry Smith Level: developer 438361b2408cSBarry Smith 438461b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 438561b2408cSBarry Smith 438661b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 438761b2408cSBarry Smith @*/ 43887087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 438961b2408cSBarry Smith { 439061b2408cSBarry Smith PetscErrorCode ierr; 439161b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 439261b2408cSBarry Smith int nlhs = 2,nrhs = 6; 439361b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 439461b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 439561b2408cSBarry Smith 439661b2408cSBarry Smith PetscFunctionBegin; 439761b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 439861b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 439961b2408cSBarry Smith 440061b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 440161b2408cSBarry Smith 440261b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 440361b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 440461b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 440561b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 440661b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 440761b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 440861b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 440961b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 441061b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 441161b2408cSBarry Smith prhs[5] = sctx->ctx; 4412b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 441361b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 441461b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 441561b2408cSBarry Smith mxDestroyArray(prhs[0]); 441661b2408cSBarry Smith mxDestroyArray(prhs[1]); 441761b2408cSBarry Smith mxDestroyArray(prhs[2]); 441861b2408cSBarry Smith mxDestroyArray(prhs[3]); 441961b2408cSBarry Smith mxDestroyArray(prhs[4]); 442061b2408cSBarry Smith mxDestroyArray(plhs[0]); 442161b2408cSBarry Smith mxDestroyArray(plhs[1]); 442261b2408cSBarry Smith PetscFunctionReturn(0); 442361b2408cSBarry Smith } 442461b2408cSBarry Smith 442561b2408cSBarry Smith 442661b2408cSBarry Smith #undef __FUNCT__ 442761b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 442861b2408cSBarry Smith /* 442961b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 443061b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4431e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 443261b2408cSBarry Smith 443361b2408cSBarry Smith Logically Collective on SNES 443461b2408cSBarry Smith 443561b2408cSBarry Smith Input Parameters: 443661b2408cSBarry Smith + snes - the SNES context 443761b2408cSBarry Smith . A,B - Jacobian matrices 443861b2408cSBarry Smith . func - function evaluation routine 443961b2408cSBarry Smith - ctx - user context 444061b2408cSBarry Smith 444161b2408cSBarry Smith Calling sequence of func: 444261b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 444361b2408cSBarry Smith 444461b2408cSBarry Smith 444561b2408cSBarry Smith Level: developer 444661b2408cSBarry Smith 444761b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 444861b2408cSBarry Smith 444961b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 445061b2408cSBarry Smith */ 44517087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 445261b2408cSBarry Smith { 445361b2408cSBarry Smith PetscErrorCode ierr; 445461b2408cSBarry Smith SNESMatlabContext *sctx; 445561b2408cSBarry Smith 445661b2408cSBarry Smith PetscFunctionBegin; 445761b2408cSBarry Smith /* currently sctx is memory bleed */ 445861b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 445961b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 446061b2408cSBarry Smith /* 446161b2408cSBarry Smith This should work, but it doesn't 446261b2408cSBarry Smith sctx->ctx = ctx; 446361b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 446461b2408cSBarry Smith */ 446561b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 446661b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 446761b2408cSBarry Smith PetscFunctionReturn(0); 446861b2408cSBarry Smith } 446969b4f73cSBarry Smith 4470f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4471f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4472f9eb7ae2SShri Abhyankar /* 4473f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4474f9eb7ae2SShri Abhyankar 4475f9eb7ae2SShri Abhyankar Collective on SNES 4476f9eb7ae2SShri Abhyankar 4477f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4478f9eb7ae2SShri Abhyankar @*/ 44797087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4480f9eb7ae2SShri Abhyankar { 4481f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 448248f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4483f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4484f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4485f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4486f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4487f9eb7ae2SShri Abhyankar 4488f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4489f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4490f9eb7ae2SShri Abhyankar 4491f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4492f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4493f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4494f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4495f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4496f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4497f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4498f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4499f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4500f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4501f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4502f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4503f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4504f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4505f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4506f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4507f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4508f9eb7ae2SShri Abhyankar } 4509f9eb7ae2SShri Abhyankar 4510f9eb7ae2SShri Abhyankar 4511f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4512f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4513f9eb7ae2SShri Abhyankar /* 4514e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4515f9eb7ae2SShri Abhyankar 4516f9eb7ae2SShri Abhyankar Level: developer 4517f9eb7ae2SShri Abhyankar 4518f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4519f9eb7ae2SShri Abhyankar 4520f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4521f9eb7ae2SShri Abhyankar */ 45227087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4523f9eb7ae2SShri Abhyankar { 4524f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4525f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4526f9eb7ae2SShri Abhyankar 4527f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4528f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4529f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4530f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4531f9eb7ae2SShri Abhyankar /* 4532f9eb7ae2SShri Abhyankar This should work, but it doesn't 4533f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4534f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4535f9eb7ae2SShri Abhyankar */ 4536f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4537f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4538f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4539f9eb7ae2SShri Abhyankar } 4540f9eb7ae2SShri Abhyankar 454169b4f73cSBarry Smith #endif 4542