19b94acceSBarry Smith 2c6db04a5SJed Brown #include <private/snesimpl.h> /*I "petscsnes.h" I*/ 39b94acceSBarry Smith 4ace3abfcSBarry Smith PetscBool SNESRegisterAllCalled = PETSC_FALSE; 58ba1e511SMatthew Knepley PetscFList SNESList = PETSC_NULL; 68ba1e511SMatthew Knepley 78ba1e511SMatthew Knepley /* Logging support */ 87087cfbeSBarry Smith PetscClassId SNES_CLASSID; 9166c7f25SBarry Smith PetscLogEvent SNES_Solve, SNES_LineSearch, SNES_FunctionEval, SNES_JacobianEval; 10a09944afSBarry Smith 11a09944afSBarry Smith #undef __FUNCT__ 12cab2e9ccSBarry Smith #define __FUNCT__ "SNESDMComputeJacobian" 13cab2e9ccSBarry Smith /* 14cab2e9ccSBarry Smith Translates from a SNES call to a DM call in computing a Jacobian 15cab2e9ccSBarry Smith */ 16cab2e9ccSBarry Smith PetscErrorCode SNESDMComputeJacobian(SNES snes,Vec X,Mat *J,Mat *B,MatStructure *flag,void *ptr) 17cab2e9ccSBarry Smith { 18cab2e9ccSBarry Smith PetscErrorCode ierr; 19cab2e9ccSBarry Smith DM dm; 20cab2e9ccSBarry Smith 21cab2e9ccSBarry Smith PetscFunctionBegin; 22cab2e9ccSBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 23cab2e9ccSBarry Smith ierr = DMComputeJacobian(dm,X,*J,*B,flag);CHKERRQ(ierr); 24cab2e9ccSBarry Smith PetscFunctionReturn(0); 25cab2e9ccSBarry Smith } 26cab2e9ccSBarry Smith 27cab2e9ccSBarry Smith #undef __FUNCT__ 28e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged" 29e113a28aSBarry Smith /*@ 30e113a28aSBarry Smith SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged. 31e113a28aSBarry Smith 323f9fe445SBarry Smith Logically Collective on SNES 33e113a28aSBarry Smith 34e113a28aSBarry Smith Input Parameters: 35e113a28aSBarry Smith + snes - iterative context obtained from SNESCreate() 36e113a28aSBarry Smith - flg - PETSC_TRUE indicates you want the error generated 37e113a28aSBarry Smith 38e113a28aSBarry Smith Options database keys: 39e113a28aSBarry Smith . -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false) 40e113a28aSBarry Smith 41e113a28aSBarry Smith Level: intermediate 42e113a28aSBarry Smith 43e113a28aSBarry Smith Notes: 44e113a28aSBarry Smith Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve() 45e113a28aSBarry Smith to determine if it has converged. 46e113a28aSBarry Smith 47e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 48e113a28aSBarry Smith 49e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 50e113a28aSBarry Smith @*/ 517087cfbeSBarry Smith PetscErrorCode SNESSetErrorIfNotConverged(SNES snes,PetscBool flg) 52e113a28aSBarry Smith { 53e113a28aSBarry Smith PetscFunctionBegin; 54e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 55acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flg,2); 56e113a28aSBarry Smith snes->errorifnotconverged = flg; 57e113a28aSBarry Smith PetscFunctionReturn(0); 58e113a28aSBarry Smith } 59e113a28aSBarry Smith 60e113a28aSBarry Smith #undef __FUNCT__ 61e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged" 62e113a28aSBarry Smith /*@ 63e113a28aSBarry Smith SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge? 64e113a28aSBarry Smith 65e113a28aSBarry Smith Not Collective 66e113a28aSBarry Smith 67e113a28aSBarry Smith Input Parameter: 68e113a28aSBarry Smith . snes - iterative context obtained from SNESCreate() 69e113a28aSBarry Smith 70e113a28aSBarry Smith Output Parameter: 71e113a28aSBarry Smith . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE 72e113a28aSBarry Smith 73e113a28aSBarry Smith Level: intermediate 74e113a28aSBarry Smith 75e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 76e113a28aSBarry Smith 77e113a28aSBarry Smith .seealso: SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 78e113a28aSBarry Smith @*/ 797087cfbeSBarry Smith PetscErrorCode SNESGetErrorIfNotConverged(SNES snes,PetscBool *flag) 80e113a28aSBarry Smith { 81e113a28aSBarry Smith PetscFunctionBegin; 82e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 83e113a28aSBarry Smith PetscValidPointer(flag,2); 84e113a28aSBarry Smith *flag = snes->errorifnotconverged; 85e113a28aSBarry Smith PetscFunctionReturn(0); 86e113a28aSBarry Smith } 87e113a28aSBarry Smith 88e113a28aSBarry Smith #undef __FUNCT__ 894936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError" 90e725d27bSBarry Smith /*@ 914936397dSBarry Smith SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not 924936397dSBarry Smith in the functions domain. For example, negative pressure. 934936397dSBarry Smith 943f9fe445SBarry Smith Logically Collective on SNES 954936397dSBarry Smith 964936397dSBarry Smith Input Parameters: 974936397dSBarry Smith . SNES - the SNES context 984936397dSBarry Smith 9928529972SSatish Balay Level: advanced 1004936397dSBarry Smith 1014936397dSBarry Smith .keywords: SNES, view 1024936397dSBarry Smith 1034936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction() 1044936397dSBarry Smith @*/ 1057087cfbeSBarry Smith PetscErrorCode SNESSetFunctionDomainError(SNES snes) 1064936397dSBarry Smith { 1074936397dSBarry Smith PetscFunctionBegin; 1080700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1094936397dSBarry Smith snes->domainerror = PETSC_TRUE; 1104936397dSBarry Smith PetscFunctionReturn(0); 1114936397dSBarry Smith } 1124936397dSBarry Smith 1134936397dSBarry Smith #undef __FUNCT__ 1144a2ae208SSatish Balay #define __FUNCT__ "SNESView" 1157e2c5f70SBarry Smith /*@C 1169b94acceSBarry Smith SNESView - Prints the SNES data structure. 1179b94acceSBarry Smith 1184c49b128SBarry Smith Collective on SNES 119fee21e36SBarry Smith 120c7afd0dbSLois Curfman McInnes Input Parameters: 121c7afd0dbSLois Curfman McInnes + SNES - the SNES context 122c7afd0dbSLois Curfman McInnes - viewer - visualization context 123c7afd0dbSLois Curfman McInnes 1249b94acceSBarry Smith Options Database Key: 125c8a8ba5cSLois Curfman McInnes . -snes_view - Calls SNESView() at end of SNESSolve() 1269b94acceSBarry Smith 1279b94acceSBarry Smith Notes: 1289b94acceSBarry Smith The available visualization contexts include 129b0a32e0cSBarry Smith + PETSC_VIEWER_STDOUT_SELF - standard output (default) 130b0a32e0cSBarry Smith - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 131c8a8ba5cSLois Curfman McInnes output where only the first processor opens 132c8a8ba5cSLois Curfman McInnes the file. All other processors send their 133c8a8ba5cSLois Curfman McInnes data to the first processor to print. 1349b94acceSBarry Smith 1353e081fefSLois Curfman McInnes The user can open an alternative visualization context with 136b0a32e0cSBarry Smith PetscViewerASCIIOpen() - output to a specified file. 1379b94acceSBarry Smith 13836851e7fSLois Curfman McInnes Level: beginner 13936851e7fSLois Curfman McInnes 1409b94acceSBarry Smith .keywords: SNES, view 1419b94acceSBarry Smith 142b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen() 1439b94acceSBarry Smith @*/ 1447087cfbeSBarry Smith PetscErrorCode SNESView(SNES snes,PetscViewer viewer) 1459b94acceSBarry Smith { 146fa9f3622SBarry Smith SNESKSPEW *kctx; 147dfbe8321SBarry Smith PetscErrorCode ierr; 14894b7f48cSBarry Smith KSP ksp; 149ace3abfcSBarry Smith PetscBool iascii,isstring; 1509b94acceSBarry Smith 1513a40ed3dSBarry Smith PetscFunctionBegin; 1520700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1533050cee2SBarry Smith if (!viewer) { 1547adad957SLisandro Dalcin ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 1553050cee2SBarry Smith } 1560700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 157c9780b6fSBarry Smith PetscCheckSameComm(snes,1,viewer,2); 15874679c65SBarry Smith 1592692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1602692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 16132077d6dSBarry Smith if (iascii) { 162317d6ea6SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr); 163e7788613SBarry Smith if (snes->ops->view) { 164b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 165e7788613SBarry Smith ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 166b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1670ef38995SBarry Smith } 16877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr); 169a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%G, absolute=%G, solution=%G\n", 17070441072SBarry Smith snes->rtol,snes->abstol,snes->xtol);CHKERRQ(ierr); 17177431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr); 17277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr); 1739b94acceSBarry Smith if (snes->ksp_ewconv) { 174fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 1759b94acceSBarry Smith if (kctx) { 17677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr); 177a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr); 178a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr); 1799b94acceSBarry Smith } 1809b94acceSBarry Smith } 181eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 182eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n");CHKERRQ(ierr); 183eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 184eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr); 185eb1f6c34SBarry Smith } 186eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 187eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n");CHKERRQ(ierr); 188eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 18942f4f86dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr); 190eb1f6c34SBarry Smith } 1910f5bd95cSBarry Smith } else if (isstring) { 192317d6ea6SBarry Smith const char *type; 193454a90a3SBarry Smith ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 194b0a32e0cSBarry Smith ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr); 19519bcc07fSBarry Smith } 19642f4f86dSBarry Smith if (snes->pc && snes->usespc) { 1974a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1984a0c5b0cSMatthew G Knepley ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr); 1994a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2004a0c5b0cSMatthew G Knepley } 2012c155ee1SBarry Smith if (snes->usesksp) { 2022c155ee1SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 203b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 20494b7f48cSBarry Smith ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 205b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2062c155ee1SBarry Smith } 2073a40ed3dSBarry Smith PetscFunctionReturn(0); 2089b94acceSBarry Smith } 2099b94acceSBarry Smith 21076b2cf59SMatthew Knepley /* 21176b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 21276b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 21376b2cf59SMatthew Knepley */ 21476b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 215a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 2166849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 21776b2cf59SMatthew Knepley 218e74ef692SMatthew Knepley #undef __FUNCT__ 219e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker" 220ac226902SBarry Smith /*@C 22176b2cf59SMatthew Knepley SNESAddOptionsChecker - Adds an additional function to check for SNES options. 22276b2cf59SMatthew Knepley 22376b2cf59SMatthew Knepley Not Collective 22476b2cf59SMatthew Knepley 22576b2cf59SMatthew Knepley Input Parameter: 22676b2cf59SMatthew Knepley . snescheck - function that checks for options 22776b2cf59SMatthew Knepley 22876b2cf59SMatthew Knepley Level: developer 22976b2cf59SMatthew Knepley 23076b2cf59SMatthew Knepley .seealso: SNESSetFromOptions() 23176b2cf59SMatthew Knepley @*/ 2327087cfbeSBarry Smith PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 23376b2cf59SMatthew Knepley { 23476b2cf59SMatthew Knepley PetscFunctionBegin; 23576b2cf59SMatthew Knepley if (numberofsetfromoptions >= MAXSETFROMOPTIONS) { 236e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 23776b2cf59SMatthew Knepley } 23876b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 23976b2cf59SMatthew Knepley PetscFunctionReturn(0); 24076b2cf59SMatthew Knepley } 24176b2cf59SMatthew Knepley 2427087cfbeSBarry Smith extern PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 243aa3661deSLisandro Dalcin 244aa3661deSLisandro Dalcin #undef __FUNCT__ 245aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private" 246ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 247aa3661deSLisandro Dalcin { 248aa3661deSLisandro Dalcin Mat J; 249aa3661deSLisandro Dalcin KSP ksp; 250aa3661deSLisandro Dalcin PC pc; 251ace3abfcSBarry Smith PetscBool match; 252aa3661deSLisandro Dalcin PetscErrorCode ierr; 253aa3661deSLisandro Dalcin 254aa3661deSLisandro Dalcin PetscFunctionBegin; 2550700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 256aa3661deSLisandro Dalcin 25798613b67SLisandro Dalcin if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 25898613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 25998613b67SLisandro Dalcin ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr); 26098613b67SLisandro Dalcin } 26198613b67SLisandro Dalcin 262aa3661deSLisandro Dalcin if (version == 1) { 263aa3661deSLisandro Dalcin ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 26498613b67SLisandro Dalcin ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 2659c6ac3b3SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 266aa3661deSLisandro Dalcin } else if (version == 2) { 267e32f2f54SBarry Smith if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 26882a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 269aa3661deSLisandro Dalcin ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr); 270aa3661deSLisandro Dalcin #else 271e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)"); 272aa3661deSLisandro Dalcin #endif 273a8248277SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2"); 274aa3661deSLisandro Dalcin 275aa3661deSLisandro Dalcin ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr); 276d3462f78SMatthew Knepley if (hasOperator) { 277aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 278aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 279aa3661deSLisandro Dalcin ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 280aa3661deSLisandro Dalcin } else { 281aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 282aa3661deSLisandro Dalcin provided preconditioner matrix with the default matrix free version. */ 283aa3661deSLisandro Dalcin ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);CHKERRQ(ierr); 284aa3661deSLisandro Dalcin /* Force no preconditioner */ 285aa3661deSLisandro Dalcin ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 286aa3661deSLisandro Dalcin ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 287aa3661deSLisandro Dalcin ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr); 288aa3661deSLisandro Dalcin if (!match) { 289aa3661deSLisandro Dalcin ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 290aa3661deSLisandro Dalcin ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 291aa3661deSLisandro Dalcin } 292aa3661deSLisandro Dalcin } 2936bf464f9SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 294aa3661deSLisandro Dalcin PetscFunctionReturn(0); 295aa3661deSLisandro Dalcin } 296aa3661deSLisandro Dalcin 2974a2ae208SSatish Balay #undef __FUNCT__ 2984a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions" 2999b94acceSBarry Smith /*@ 30094b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 3019b94acceSBarry Smith 302c7afd0dbSLois Curfman McInnes Collective on SNES 303c7afd0dbSLois Curfman McInnes 3049b94acceSBarry Smith Input Parameter: 3059b94acceSBarry Smith . snes - the SNES context 3069b94acceSBarry Smith 30736851e7fSLois Curfman McInnes Options Database Keys: 308ea630c6eSPeter Brune + -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas 30982738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 31082738288SBarry Smith of the change in the solution between steps 31170441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 312b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 313b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 314b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 31550ffb88aSMatthew Knepley . -snes_max_fail <max_fail> - maximum number of failures 316ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 317a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 318e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 319b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 3202492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 32182738288SBarry Smith solver; hence iterations will continue until max_it 3221fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 32382738288SBarry Smith of convergence test 324e8105e01SRichard Katz . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 325e8105e01SRichard Katz filename given prints to stdout 326a6570f20SBarry Smith . -snes_monitor_solution - plots solution at each iteration 327a6570f20SBarry Smith . -snes_monitor_residual - plots residual (not its norm) at each iteration 328a6570f20SBarry Smith . -snes_monitor_solution_update - plots update to solution at each iteration 329a6570f20SBarry Smith . -snes_monitor_draw - plots residual norm at each iteration 330e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 3315968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 332fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 33382738288SBarry Smith 33482738288SBarry Smith Options Database for Eisenstat-Walker method: 335fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 3364b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 33736851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 33836851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 33936851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 34036851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 34136851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 34236851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 34382738288SBarry Smith 34411ca99fdSLois Curfman McInnes Notes: 34511ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 3460598bfebSBarry Smith the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>. 34783e2fdc7SBarry Smith 34836851e7fSLois Curfman McInnes Level: beginner 34936851e7fSLois Curfman McInnes 3509b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 3519b94acceSBarry Smith 35269ed319cSSatish Balay .seealso: SNESSetOptionsPrefix() 3539b94acceSBarry Smith @*/ 3547087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 3559b94acceSBarry Smith { 356ea630c6eSPeter Brune PetscBool flg,set,mf,mf_operator,pcset; 357efd51863SBarry Smith PetscInt i,indx,lag,mf_version,grids; 358aa3661deSLisandro Dalcin MatStructure matflag; 35985385478SLisandro Dalcin const char *deft = SNESLS; 36085385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 36185385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 362e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 36351e86f29SPeter Brune const char *optionsprefix; 364649052a6SBarry Smith PetscViewer monviewer; 36585385478SLisandro Dalcin PetscErrorCode ierr; 3669b94acceSBarry Smith 3673a40ed3dSBarry Smith PetscFunctionBegin; 3680700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 369ca161407SBarry Smith 370186905e3SBarry Smith if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 3713194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 3727adad957SLisandro Dalcin if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; } 373b0a32e0cSBarry Smith ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 374d64ed03dSBarry Smith if (flg) { 375186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 3767adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 377186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 378d64ed03dSBarry Smith } 37990d69ab7SBarry Smith /* not used here, but called so will go into help messaage */ 380909c8a9fSBarry Smith ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 38193c39befSBarry Smith 38257034d6fSHong Zhang ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->xtol,&snes->xtol,0);CHKERRQ(ierr); 38357034d6fSHong Zhang ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 384186905e3SBarry Smith 38557034d6fSHong Zhang ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 386b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 387b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 38850ffb88aSMatthew Knepley ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 389ddf469c8SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr); 390acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr); 39185385478SLisandro Dalcin 392a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 393a8054027SBarry Smith if (flg) { 394a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 395a8054027SBarry Smith } 396e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 397e35cf81dSBarry Smith if (flg) { 398e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 399e35cf81dSBarry Smith } 400efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 401efd51863SBarry Smith if (flg) { 402efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 403efd51863SBarry Smith } 404a8054027SBarry Smith 40585385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 40685385478SLisandro Dalcin if (flg) { 40785385478SLisandro Dalcin switch (indx) { 4087f7931b9SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 4097f7931b9SBarry Smith case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 41085385478SLisandro Dalcin } 41185385478SLisandro Dalcin } 41285385478SLisandro Dalcin 413acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr); 414186905e3SBarry Smith 41585385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 41685385478SLisandro Dalcin 417acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 418186905e3SBarry Smith 419fa9f3622SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 420fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 421fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 422fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 423fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 424fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 425fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 426186905e3SBarry Smith 42790d69ab7SBarry Smith flg = PETSC_FALSE; 428acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 429a6570f20SBarry Smith if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 430eabae89aSBarry Smith 431a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 432e8105e01SRichard Katz if (flg) { 433649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 434649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 435e8105e01SRichard Katz } 436eabae89aSBarry Smith 437b271bb04SBarry Smith ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 438b271bb04SBarry Smith if (flg) { 439b271bb04SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 440b271bb04SBarry Smith } 441b271bb04SBarry Smith 442a6570f20SBarry Smith ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 443eabae89aSBarry Smith if (flg) { 444649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 445f1bef1bcSMatthew Knepley ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 446e8105e01SRichard Katz } 447eabae89aSBarry Smith 448a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 449eabae89aSBarry Smith if (flg) { 450649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 451649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 452eabae89aSBarry Smith } 453eabae89aSBarry Smith 4545180491cSLisandro Dalcin ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 4555180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 4565180491cSLisandro Dalcin 45790d69ab7SBarry Smith flg = PETSC_FALSE; 458acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 459a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 46090d69ab7SBarry Smith flg = PETSC_FALSE; 461acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 462a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 46390d69ab7SBarry Smith flg = PETSC_FALSE; 464acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 465a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 46690d69ab7SBarry Smith flg = PETSC_FALSE; 467acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 468a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 46990d69ab7SBarry Smith flg = PETSC_FALSE; 470acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 471b271bb04SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 472e24b481bSBarry Smith 47390d69ab7SBarry Smith flg = PETSC_FALSE; 474acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 4754b27c08aSLois Curfman McInnes if (flg) { 476186905e3SBarry Smith ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);CHKERRQ(ierr); 477ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 4789b94acceSBarry Smith } 479639f9d9dSBarry Smith 480aa3661deSLisandro Dalcin mf = mf_operator = PETSC_FALSE; 481aa3661deSLisandro Dalcin flg = PETSC_FALSE; 482acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr); 483a8248277SBarry Smith if (flg && mf_operator) { 484a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 485a8248277SBarry Smith mf = PETSC_TRUE; 486a8248277SBarry Smith } 487aa3661deSLisandro Dalcin flg = PETSC_FALSE; 488acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr); 489aa3661deSLisandro Dalcin if (!flg && mf_operator) mf = PETSC_TRUE; 490aa3661deSLisandro Dalcin mf_version = 1; 491aa3661deSLisandro Dalcin ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr); 492aa3661deSLisandro Dalcin 493ea630c6eSPeter Brune /* line search options */ 494ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_alpha","Constant function norm must decrease by","None",snes->ls_alpha,&snes->ls_alpha,0);CHKERRQ(ierr); 495ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_maxstep","Step must be less than","None",snes->maxstep,&snes->maxstep,0);CHKERRQ(ierr); 496ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_steptol","Minimum lambda allowed","None",snes->steptol,&snes->steptol,0);CHKERRQ(ierr); 497ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_damping","Damping parameter","SNES",snes->damping,&snes->damping,&flg);CHKERRQ(ierr); 498ea630c6eSPeter Brune ierr = PetscOptionsBool("-snes_ls_monitor","Print progress of line searches","SNESLineSearchSetMonitor",snes->ls_monitor ? PETSC_TRUE : PETSC_FALSE,&flg,&set);CHKERRQ(ierr); 499ea630c6eSPeter Brune if (set) {ierr = SNESLineSearchSetMonitor(snes,flg);CHKERRQ(ierr);} 50015f5eeeaSPeter Brune ierr = PetscOptionsEnum("-snes_ls","Line search used","SNESLineSearchSet",SNESLineSearchTypes,(PetscEnum)snes->ls_type,(PetscEnum*)&indx,&flg);CHKERRQ(ierr); 50115f5eeeaSPeter Brune if (flg) { 502ea630c6eSPeter Brune ierr = SNESLineSearchSetType(snes,(SNESLineSearchType)indx);CHKERRQ(ierr); 50315f5eeeaSPeter Brune } 5048e3fc8c0SJed Brown flg = snes->ops->precheckstep == SNESLineSearchPreCheckPicard ? PETSC_TRUE : PETSC_FALSE; 5058e3fc8c0SJed Brown ierr = PetscOptionsBool("-snes_ls_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);CHKERRQ(ierr); 5068e3fc8c0SJed Brown if (set) { 5078e3fc8c0SJed Brown if (flg) { 5088e3fc8c0SJed Brown snes->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */ 5098e3fc8c0SJed Brown ierr = PetscOptionsReal("-snes_ls_precheck_picard_angle","Maximum angle at which to activate the correction","none",snes->precheck_picard_angle,&snes->precheck_picard_angle,PETSC_NULL);CHKERRQ(ierr); 5108e3fc8c0SJed Brown ierr = SNESLineSearchSetPreCheck(snes,SNESLineSearchPreCheckPicard,&snes->precheck_picard_angle);CHKERRQ(ierr); 5118e3fc8c0SJed Brown } else { 5128e3fc8c0SJed Brown ierr = SNESLineSearchSetPreCheck(snes,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 5138e3fc8c0SJed Brown } 5148e3fc8c0SJed Brown } 5158e3fc8c0SJed Brown 51676b2cf59SMatthew Knepley for(i = 0; i < numberofsetfromoptions; i++) { 51776b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 51876b2cf59SMatthew Knepley } 51976b2cf59SMatthew Knepley 520e7788613SBarry Smith if (snes->ops->setfromoptions) { 521e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 522639f9d9dSBarry Smith } 5235d973c19SBarry Smith 5245d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 5255d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 526b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 5274bbc92c1SBarry Smith 528aa3661deSLisandro Dalcin if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 5291cee3971SBarry Smith 5301cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 531aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 532aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 53385385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 53493993e2dSLois Curfman McInnes 53551e86f29SPeter Brune /* if someone has set the SNES PC type, create it. */ 53651e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 53751e86f29SPeter Brune ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 53851e86f29SPeter Brune if (pcset && (!snes->pc)) { 53951e86f29SPeter Brune ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr); 54051e86f29SPeter Brune } 54151e86f29SPeter Brune 5424a0c5b0cSMatthew G Knepley if (snes->pc) { 5434a0c5b0cSMatthew G Knepley ierr = SNESSetOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr); 5444a0c5b0cSMatthew G Knepley ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 5454a0c5b0cSMatthew G Knepley /* Should we make a duplicate vector and matrix? Leave the DM to make it? */ 5464a0c5b0cSMatthew G Knepley ierr = SNESSetFunction(snes->pc, snes->vec_func, snes->ops->computefunction, snes->funP);CHKERRQ(ierr); 5474a0c5b0cSMatthew G Knepley ierr = SNESSetJacobian(snes->pc, snes->jacobian, snes->jacobian_pre, snes->ops->computejacobian, snes->jacP);CHKERRQ(ierr); 5484a0c5b0cSMatthew G Knepley ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 5494a0c5b0cSMatthew G Knepley } 5503a40ed3dSBarry Smith PetscFunctionReturn(0); 5519b94acceSBarry Smith } 5529b94acceSBarry Smith 553d25893d9SBarry Smith #undef __FUNCT__ 554d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 555d25893d9SBarry Smith /*@ 556d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 557d25893d9SBarry Smith the nonlinear solvers. 558d25893d9SBarry Smith 559d25893d9SBarry Smith Logically Collective on SNES 560d25893d9SBarry Smith 561d25893d9SBarry Smith Input Parameters: 562d25893d9SBarry Smith + snes - the SNES context 563d25893d9SBarry Smith . compute - function to compute the context 564d25893d9SBarry Smith - destroy - function to destroy the context 565d25893d9SBarry Smith 566d25893d9SBarry Smith Level: intermediate 567d25893d9SBarry Smith 568d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 569d25893d9SBarry Smith 570d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 571d25893d9SBarry Smith @*/ 572d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 573d25893d9SBarry Smith { 574d25893d9SBarry Smith PetscFunctionBegin; 575d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 576d25893d9SBarry Smith snes->ops->usercompute = compute; 577d25893d9SBarry Smith snes->ops->userdestroy = destroy; 578d25893d9SBarry Smith PetscFunctionReturn(0); 579d25893d9SBarry Smith } 580a847f771SSatish Balay 5814a2ae208SSatish Balay #undef __FUNCT__ 5824a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 583b07ff414SBarry Smith /*@ 5849b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 5859b94acceSBarry Smith the nonlinear solvers. 5869b94acceSBarry Smith 5873f9fe445SBarry Smith Logically Collective on SNES 588fee21e36SBarry Smith 589c7afd0dbSLois Curfman McInnes Input Parameters: 590c7afd0dbSLois Curfman McInnes + snes - the SNES context 591c7afd0dbSLois Curfman McInnes - usrP - optional user context 592c7afd0dbSLois Curfman McInnes 59336851e7fSLois Curfman McInnes Level: intermediate 59436851e7fSLois Curfman McInnes 5959b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 5969b94acceSBarry Smith 597d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext() 5989b94acceSBarry Smith @*/ 5997087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 6009b94acceSBarry Smith { 6011b2093e4SBarry Smith PetscErrorCode ierr; 602b07ff414SBarry Smith KSP ksp; 6031b2093e4SBarry Smith 6043a40ed3dSBarry Smith PetscFunctionBegin; 6050700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 606b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 607b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 6089b94acceSBarry Smith snes->user = usrP; 6093a40ed3dSBarry Smith PetscFunctionReturn(0); 6109b94acceSBarry Smith } 61174679c65SBarry Smith 6124a2ae208SSatish Balay #undef __FUNCT__ 6134a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 614b07ff414SBarry Smith /*@ 6159b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 6169b94acceSBarry Smith nonlinear solvers. 6179b94acceSBarry Smith 618c7afd0dbSLois Curfman McInnes Not Collective 619c7afd0dbSLois Curfman McInnes 6209b94acceSBarry Smith Input Parameter: 6219b94acceSBarry Smith . snes - SNES context 6229b94acceSBarry Smith 6239b94acceSBarry Smith Output Parameter: 6249b94acceSBarry Smith . usrP - user context 6259b94acceSBarry Smith 62636851e7fSLois Curfman McInnes Level: intermediate 62736851e7fSLois Curfman McInnes 6289b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 6299b94acceSBarry Smith 6309b94acceSBarry Smith .seealso: SNESSetApplicationContext() 6319b94acceSBarry Smith @*/ 632e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 6339b94acceSBarry Smith { 6343a40ed3dSBarry Smith PetscFunctionBegin; 6350700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 636e71120c6SJed Brown *(void**)usrP = snes->user; 6373a40ed3dSBarry Smith PetscFunctionReturn(0); 6389b94acceSBarry Smith } 63974679c65SBarry Smith 6404a2ae208SSatish Balay #undef __FUNCT__ 6414a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 6429b94acceSBarry Smith /*@ 643c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 644c8228a4eSBarry Smith at this time. 6459b94acceSBarry Smith 646c7afd0dbSLois Curfman McInnes Not Collective 647c7afd0dbSLois Curfman McInnes 6489b94acceSBarry Smith Input Parameter: 6499b94acceSBarry Smith . snes - SNES context 6509b94acceSBarry Smith 6519b94acceSBarry Smith Output Parameter: 6529b94acceSBarry Smith . iter - iteration number 6539b94acceSBarry Smith 654c8228a4eSBarry Smith Notes: 655c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 656c8228a4eSBarry Smith 657c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 65808405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 65908405cd6SLois Curfman McInnes .vb 66008405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 66108405cd6SLois Curfman McInnes if (!(it % 2)) { 66208405cd6SLois Curfman McInnes [compute Jacobian here] 66308405cd6SLois Curfman McInnes } 66408405cd6SLois Curfman McInnes .ve 665c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 66608405cd6SLois Curfman McInnes recomputed every second SNES iteration. 667c8228a4eSBarry Smith 66836851e7fSLois Curfman McInnes Level: intermediate 66936851e7fSLois Curfman McInnes 6702b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 6712b668275SBarry Smith 672b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 6739b94acceSBarry Smith @*/ 6747087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 6759b94acceSBarry Smith { 6763a40ed3dSBarry Smith PetscFunctionBegin; 6770700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 6784482741eSBarry Smith PetscValidIntPointer(iter,2); 6799b94acceSBarry Smith *iter = snes->iter; 6803a40ed3dSBarry Smith PetscFunctionReturn(0); 6819b94acceSBarry Smith } 68274679c65SBarry Smith 6834a2ae208SSatish Balay #undef __FUNCT__ 6844a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 6859b94acceSBarry Smith /*@ 6869b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 6879b94acceSBarry Smith with SNESSSetFunction(). 6889b94acceSBarry Smith 689c7afd0dbSLois Curfman McInnes Collective on SNES 690c7afd0dbSLois Curfman McInnes 6919b94acceSBarry Smith Input Parameter: 6929b94acceSBarry Smith . snes - SNES context 6939b94acceSBarry Smith 6949b94acceSBarry Smith Output Parameter: 6959b94acceSBarry Smith . fnorm - 2-norm of function 6969b94acceSBarry Smith 69736851e7fSLois Curfman McInnes Level: intermediate 69836851e7fSLois Curfman McInnes 6999b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 700a86d99e1SLois Curfman McInnes 701b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 7029b94acceSBarry Smith @*/ 7037087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 7049b94acceSBarry Smith { 7053a40ed3dSBarry Smith PetscFunctionBegin; 7060700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7074482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 7089b94acceSBarry Smith *fnorm = snes->norm; 7093a40ed3dSBarry Smith PetscFunctionReturn(0); 7109b94acceSBarry Smith } 71174679c65SBarry Smith 7124a2ae208SSatish Balay #undef __FUNCT__ 713b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 7149b94acceSBarry Smith /*@ 715b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 7169b94acceSBarry Smith attempted by the nonlinear solver. 7179b94acceSBarry Smith 718c7afd0dbSLois Curfman McInnes Not Collective 719c7afd0dbSLois Curfman McInnes 7209b94acceSBarry Smith Input Parameter: 7219b94acceSBarry Smith . snes - SNES context 7229b94acceSBarry Smith 7239b94acceSBarry Smith Output Parameter: 7249b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 7259b94acceSBarry Smith 726c96a6f78SLois Curfman McInnes Notes: 727c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 728c96a6f78SLois Curfman McInnes 72936851e7fSLois Curfman McInnes Level: intermediate 73036851e7fSLois Curfman McInnes 7319b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 73258ebbce7SBarry Smith 733e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 73458ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 7359b94acceSBarry Smith @*/ 7367087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 7379b94acceSBarry Smith { 7383a40ed3dSBarry Smith PetscFunctionBegin; 7390700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7404482741eSBarry Smith PetscValidIntPointer(nfails,2); 74150ffb88aSMatthew Knepley *nfails = snes->numFailures; 74250ffb88aSMatthew Knepley PetscFunctionReturn(0); 74350ffb88aSMatthew Knepley } 74450ffb88aSMatthew Knepley 74550ffb88aSMatthew Knepley #undef __FUNCT__ 746b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 74750ffb88aSMatthew Knepley /*@ 748b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 74950ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 75050ffb88aSMatthew Knepley 75150ffb88aSMatthew Knepley Not Collective 75250ffb88aSMatthew Knepley 75350ffb88aSMatthew Knepley Input Parameters: 75450ffb88aSMatthew Knepley + snes - SNES context 75550ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 75650ffb88aSMatthew Knepley 75750ffb88aSMatthew Knepley Level: intermediate 75850ffb88aSMatthew Knepley 75950ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 76058ebbce7SBarry Smith 761e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 76258ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 76350ffb88aSMatthew Knepley @*/ 7647087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 76550ffb88aSMatthew Knepley { 76650ffb88aSMatthew Knepley PetscFunctionBegin; 7670700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 76850ffb88aSMatthew Knepley snes->maxFailures = maxFails; 76950ffb88aSMatthew Knepley PetscFunctionReturn(0); 77050ffb88aSMatthew Knepley } 77150ffb88aSMatthew Knepley 77250ffb88aSMatthew Knepley #undef __FUNCT__ 773b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 77450ffb88aSMatthew Knepley /*@ 775b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 77650ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 77750ffb88aSMatthew Knepley 77850ffb88aSMatthew Knepley Not Collective 77950ffb88aSMatthew Knepley 78050ffb88aSMatthew Knepley Input Parameter: 78150ffb88aSMatthew Knepley . snes - SNES context 78250ffb88aSMatthew Knepley 78350ffb88aSMatthew Knepley Output Parameter: 78450ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 78550ffb88aSMatthew Knepley 78650ffb88aSMatthew Knepley Level: intermediate 78750ffb88aSMatthew Knepley 78850ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 78958ebbce7SBarry Smith 790e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 79158ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 79258ebbce7SBarry Smith 79350ffb88aSMatthew Knepley @*/ 7947087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 79550ffb88aSMatthew Knepley { 79650ffb88aSMatthew Knepley PetscFunctionBegin; 7970700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7984482741eSBarry Smith PetscValidIntPointer(maxFails,2); 79950ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 8003a40ed3dSBarry Smith PetscFunctionReturn(0); 8019b94acceSBarry Smith } 802a847f771SSatish Balay 8034a2ae208SSatish Balay #undef __FUNCT__ 8042541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 8052541af92SBarry Smith /*@ 8062541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 8072541af92SBarry Smith done by SNES. 8082541af92SBarry Smith 8092541af92SBarry Smith Not Collective 8102541af92SBarry Smith 8112541af92SBarry Smith Input Parameter: 8122541af92SBarry Smith . snes - SNES context 8132541af92SBarry Smith 8142541af92SBarry Smith Output Parameter: 8152541af92SBarry Smith . nfuncs - number of evaluations 8162541af92SBarry Smith 8172541af92SBarry Smith Level: intermediate 8182541af92SBarry Smith 8192541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 82058ebbce7SBarry Smith 821e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 8222541af92SBarry Smith @*/ 8237087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 8242541af92SBarry Smith { 8252541af92SBarry Smith PetscFunctionBegin; 8260700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8272541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 8282541af92SBarry Smith *nfuncs = snes->nfuncs; 8292541af92SBarry Smith PetscFunctionReturn(0); 8302541af92SBarry Smith } 8312541af92SBarry Smith 8322541af92SBarry Smith #undef __FUNCT__ 8333d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 8343d4c4710SBarry Smith /*@ 8353d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 8363d4c4710SBarry Smith linear solvers. 8373d4c4710SBarry Smith 8383d4c4710SBarry Smith Not Collective 8393d4c4710SBarry Smith 8403d4c4710SBarry Smith Input Parameter: 8413d4c4710SBarry Smith . snes - SNES context 8423d4c4710SBarry Smith 8433d4c4710SBarry Smith Output Parameter: 8443d4c4710SBarry Smith . nfails - number of failed solves 8453d4c4710SBarry Smith 8463d4c4710SBarry Smith Notes: 8473d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 8483d4c4710SBarry Smith 8493d4c4710SBarry Smith Level: intermediate 8503d4c4710SBarry Smith 8513d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 85258ebbce7SBarry Smith 853e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 8543d4c4710SBarry Smith @*/ 8557087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 8563d4c4710SBarry Smith { 8573d4c4710SBarry Smith PetscFunctionBegin; 8580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8593d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 8603d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 8613d4c4710SBarry Smith PetscFunctionReturn(0); 8623d4c4710SBarry Smith } 8633d4c4710SBarry Smith 8643d4c4710SBarry Smith #undef __FUNCT__ 8653d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 8663d4c4710SBarry Smith /*@ 8673d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 8683d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 8693d4c4710SBarry Smith 8703f9fe445SBarry Smith Logically Collective on SNES 8713d4c4710SBarry Smith 8723d4c4710SBarry Smith Input Parameters: 8733d4c4710SBarry Smith + snes - SNES context 8743d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 8753d4c4710SBarry Smith 8763d4c4710SBarry Smith Level: intermediate 8773d4c4710SBarry Smith 878a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 8793d4c4710SBarry Smith 8803d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 8813d4c4710SBarry Smith 88258ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 8833d4c4710SBarry Smith @*/ 8847087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 8853d4c4710SBarry Smith { 8863d4c4710SBarry Smith PetscFunctionBegin; 8870700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 888c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 8893d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 8903d4c4710SBarry Smith PetscFunctionReturn(0); 8913d4c4710SBarry Smith } 8923d4c4710SBarry Smith 8933d4c4710SBarry Smith #undef __FUNCT__ 8943d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 8953d4c4710SBarry Smith /*@ 8963d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 8973d4c4710SBarry Smith are allowed before SNES terminates 8983d4c4710SBarry Smith 8993d4c4710SBarry Smith Not Collective 9003d4c4710SBarry Smith 9013d4c4710SBarry Smith Input Parameter: 9023d4c4710SBarry Smith . snes - SNES context 9033d4c4710SBarry Smith 9043d4c4710SBarry Smith Output Parameter: 9053d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 9063d4c4710SBarry Smith 9073d4c4710SBarry Smith Level: intermediate 9083d4c4710SBarry Smith 9093d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 9103d4c4710SBarry Smith 9113d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 9123d4c4710SBarry Smith 913e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 9143d4c4710SBarry Smith @*/ 9157087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 9163d4c4710SBarry Smith { 9173d4c4710SBarry Smith PetscFunctionBegin; 9180700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9193d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 9203d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 9213d4c4710SBarry Smith PetscFunctionReturn(0); 9223d4c4710SBarry Smith } 9233d4c4710SBarry Smith 9243d4c4710SBarry Smith #undef __FUNCT__ 925b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 926c96a6f78SLois Curfman McInnes /*@ 927b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 928c96a6f78SLois Curfman McInnes used by the nonlinear solver. 929c96a6f78SLois Curfman McInnes 930c7afd0dbSLois Curfman McInnes Not Collective 931c7afd0dbSLois Curfman McInnes 932c96a6f78SLois Curfman McInnes Input Parameter: 933c96a6f78SLois Curfman McInnes . snes - SNES context 934c96a6f78SLois Curfman McInnes 935c96a6f78SLois Curfman McInnes Output Parameter: 936c96a6f78SLois Curfman McInnes . lits - number of linear iterations 937c96a6f78SLois Curfman McInnes 938c96a6f78SLois Curfman McInnes Notes: 939c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 940c96a6f78SLois Curfman McInnes 94136851e7fSLois Curfman McInnes Level: intermediate 94236851e7fSLois Curfman McInnes 943c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 9442b668275SBarry Smith 9458c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 946c96a6f78SLois Curfman McInnes @*/ 9477087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 948c96a6f78SLois Curfman McInnes { 9493a40ed3dSBarry Smith PetscFunctionBegin; 9500700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9514482741eSBarry Smith PetscValidIntPointer(lits,2); 952c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 9533a40ed3dSBarry Smith PetscFunctionReturn(0); 954c96a6f78SLois Curfman McInnes } 955c96a6f78SLois Curfman McInnes 9564a2ae208SSatish Balay #undef __FUNCT__ 95794b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 95852baeb72SSatish Balay /*@ 95994b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 9609b94acceSBarry Smith 96194b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 962c7afd0dbSLois Curfman McInnes 9639b94acceSBarry Smith Input Parameter: 9649b94acceSBarry Smith . snes - the SNES context 9659b94acceSBarry Smith 9669b94acceSBarry Smith Output Parameter: 96794b7f48cSBarry Smith . ksp - the KSP context 9689b94acceSBarry Smith 9699b94acceSBarry Smith Notes: 97094b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 9719b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 9722999313aSBarry Smith PC contexts as well. 9739b94acceSBarry Smith 97436851e7fSLois Curfman McInnes Level: beginner 97536851e7fSLois Curfman McInnes 97694b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 9779b94acceSBarry Smith 9782999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 9799b94acceSBarry Smith @*/ 9807087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 9819b94acceSBarry Smith { 9821cee3971SBarry Smith PetscErrorCode ierr; 9831cee3971SBarry Smith 9843a40ed3dSBarry Smith PetscFunctionBegin; 9850700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9864482741eSBarry Smith PetscValidPointer(ksp,2); 9871cee3971SBarry Smith 9881cee3971SBarry Smith if (!snes->ksp) { 9891cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 9901cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 9911cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 9921cee3971SBarry Smith } 99394b7f48cSBarry Smith *ksp = snes->ksp; 9943a40ed3dSBarry Smith PetscFunctionReturn(0); 9959b94acceSBarry Smith } 99682bf6240SBarry Smith 9974a2ae208SSatish Balay #undef __FUNCT__ 9982999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 9992999313aSBarry Smith /*@ 10002999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 10012999313aSBarry Smith 10022999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 10032999313aSBarry Smith 10042999313aSBarry Smith Input Parameters: 10052999313aSBarry Smith + snes - the SNES context 10062999313aSBarry Smith - ksp - the KSP context 10072999313aSBarry Smith 10082999313aSBarry Smith Notes: 10092999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 10102999313aSBarry Smith so this routine is rarely needed. 10112999313aSBarry Smith 10122999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 10132999313aSBarry Smith decreased by one. 10142999313aSBarry Smith 10152999313aSBarry Smith Level: developer 10162999313aSBarry Smith 10172999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 10182999313aSBarry Smith 10192999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 10202999313aSBarry Smith @*/ 10217087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 10222999313aSBarry Smith { 10232999313aSBarry Smith PetscErrorCode ierr; 10242999313aSBarry Smith 10252999313aSBarry Smith PetscFunctionBegin; 10260700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10270700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 10282999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 10297dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1030906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 10312999313aSBarry Smith snes->ksp = ksp; 10322999313aSBarry Smith PetscFunctionReturn(0); 10332999313aSBarry Smith } 10342999313aSBarry Smith 10357adad957SLisandro Dalcin #if 0 10362999313aSBarry Smith #undef __FUNCT__ 10374a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 10386849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1039e24b481bSBarry Smith { 1040e24b481bSBarry Smith PetscFunctionBegin; 1041e24b481bSBarry Smith PetscFunctionReturn(0); 1042e24b481bSBarry Smith } 10437adad957SLisandro Dalcin #endif 1044e24b481bSBarry Smith 10459b94acceSBarry Smith /* -----------------------------------------------------------*/ 10464a2ae208SSatish Balay #undef __FUNCT__ 10474a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 104852baeb72SSatish Balay /*@ 10499b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 10509b94acceSBarry Smith 1051c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1052c7afd0dbSLois Curfman McInnes 1053c7afd0dbSLois Curfman McInnes Input Parameters: 1054906ed7ccSBarry Smith . comm - MPI communicator 10559b94acceSBarry Smith 10569b94acceSBarry Smith Output Parameter: 10579b94acceSBarry Smith . outsnes - the new SNES context 10589b94acceSBarry Smith 1059c7afd0dbSLois Curfman McInnes Options Database Keys: 1060c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1061c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1062c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1063c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1064c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1065c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1066c1f60f51SBarry Smith 106736851e7fSLois Curfman McInnes Level: beginner 106836851e7fSLois Curfman McInnes 10699b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 10709b94acceSBarry Smith 1071a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1072a8054027SBarry Smith 10739b94acceSBarry Smith @*/ 10747087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 10759b94acceSBarry Smith { 1076dfbe8321SBarry Smith PetscErrorCode ierr; 10779b94acceSBarry Smith SNES snes; 1078fa9f3622SBarry Smith SNESKSPEW *kctx; 107937fcc0dbSBarry Smith 10803a40ed3dSBarry Smith PetscFunctionBegin; 1081ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 10828ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 10838ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 10848ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 10858ba1e511SMatthew Knepley #endif 10868ba1e511SMatthew Knepley 10873194b578SJed Brown ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 10887adad957SLisandro Dalcin 108985385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 10902c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 10919b94acceSBarry Smith snes->max_its = 50; 10929750a799SBarry Smith snes->max_funcs = 10000; 10939b94acceSBarry Smith snes->norm = 0.0; 1094b4874afaSBarry Smith snes->rtol = 1.e-8; 1095b4874afaSBarry Smith snes->ttol = 0.0; 109670441072SBarry Smith snes->abstol = 1.e-50; 10979b94acceSBarry Smith snes->xtol = 1.e-8; 10984b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 10999b94acceSBarry Smith snes->nfuncs = 0; 110050ffb88aSMatthew Knepley snes->numFailures = 0; 110150ffb88aSMatthew Knepley snes->maxFailures = 1; 11027a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1103e35cf81dSBarry Smith snes->lagjacobian = 1; 1104a8054027SBarry Smith snes->lagpreconditioner = 1; 1105639f9d9dSBarry Smith snes->numbermonitors = 0; 11069b94acceSBarry Smith snes->data = 0; 11074dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1108186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 11096f24a144SLois Curfman McInnes snes->nwork = 0; 111058c9b817SLisandro Dalcin snes->work = 0; 111158c9b817SLisandro Dalcin snes->nvwork = 0; 111258c9b817SLisandro Dalcin snes->vwork = 0; 1113758f92a0SBarry Smith snes->conv_hist_len = 0; 1114758f92a0SBarry Smith snes->conv_hist_max = 0; 1115758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1116758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1117758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1118184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 11199b94acceSBarry Smith 1120ea630c6eSPeter Brune /* initialize the line search options */ 1121ea630c6eSPeter Brune snes->ls_type = SNES_LS_BASIC; 1122ea630c6eSPeter Brune snes->damping = 1.0; 1123ea630c6eSPeter Brune snes->maxstep = 1e8; 1124ea630c6eSPeter Brune snes->steptol = 1e-12; 1125ea630c6eSPeter Brune snes->ls_alpha = 1e-4; 1126ea630c6eSPeter Brune snes->ls_monitor = PETSC_NULL; 1127ea630c6eSPeter Brune 1128ea630c6eSPeter Brune snes->ops->linesearch = PETSC_NULL; 1129ea630c6eSPeter Brune snes->precheck = PETSC_NULL; 1130ea630c6eSPeter Brune snes->ops->precheckstep = PETSC_NULL; 1131ea630c6eSPeter Brune snes->postcheck = PETSC_NULL; 1132ea630c6eSPeter Brune snes->ops->postcheckstep= PETSC_NULL; 1133ea630c6eSPeter Brune 11343d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 11353d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 11363d4c4710SBarry Smith 11379b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 113838f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 11399b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 11409b94acceSBarry Smith kctx->version = 2; 11419b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 11429b94acceSBarry Smith this was too large for some test cases */ 114375567043SBarry Smith kctx->rtol_last = 0.0; 11449b94acceSBarry Smith kctx->rtol_max = .9; 11459b94acceSBarry Smith kctx->gamma = 1.0; 114671f87433Sdalcinl kctx->alpha = .5*(1.0 + sqrt(5.0)); 114771f87433Sdalcinl kctx->alpha2 = kctx->alpha; 11489b94acceSBarry Smith kctx->threshold = .1; 114975567043SBarry Smith kctx->lresid_last = 0.0; 115075567043SBarry Smith kctx->norm_last = 0.0; 11519b94acceSBarry Smith 11529b94acceSBarry Smith *outsnes = snes; 11533a40ed3dSBarry Smith PetscFunctionReturn(0); 11549b94acceSBarry Smith } 11559b94acceSBarry Smith 11564a2ae208SSatish Balay #undef __FUNCT__ 11574a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 11589b94acceSBarry Smith /*@C 11599b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 11609b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 11619b94acceSBarry Smith equations. 11629b94acceSBarry Smith 11633f9fe445SBarry Smith Logically Collective on SNES 1164fee21e36SBarry Smith 1165c7afd0dbSLois Curfman McInnes Input Parameters: 1166c7afd0dbSLois Curfman McInnes + snes - the SNES context 1167c7afd0dbSLois Curfman McInnes . r - vector to store function value 1168de044059SHong Zhang . func - function evaluation routine 1169c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1170c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 11719b94acceSBarry Smith 1172c7afd0dbSLois Curfman McInnes Calling sequence of func: 11738d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1174c7afd0dbSLois Curfman McInnes 1175313e4042SLois Curfman McInnes . f - function vector 1176c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 11779b94acceSBarry Smith 11789b94acceSBarry Smith Notes: 11799b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 11809b94acceSBarry Smith $ f'(x) x = -f(x), 1181c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 11829b94acceSBarry Smith 118336851e7fSLois Curfman McInnes Level: beginner 118436851e7fSLois Curfman McInnes 11859b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 11869b94acceSBarry Smith 1187a86d99e1SLois Curfman McInnes .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 11889b94acceSBarry Smith @*/ 11897087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 11909b94acceSBarry Smith { 119185385478SLisandro Dalcin PetscErrorCode ierr; 11923a40ed3dSBarry Smith PetscFunctionBegin; 11930700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1194d2a683ecSLisandro Dalcin if (r) { 1195d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1196d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 119785385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 11986bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 119985385478SLisandro Dalcin snes->vec_func = r; 1200d2a683ecSLisandro Dalcin } else if (!snes->vec_func && snes->dm) { 1201d2a683ecSLisandro Dalcin ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 1202d2a683ecSLisandro Dalcin } 1203d2a683ecSLisandro Dalcin if (func) snes->ops->computefunction = func; 1204d2a683ecSLisandro Dalcin if (ctx) snes->funP = ctx; 12053a40ed3dSBarry Smith PetscFunctionReturn(0); 12069b94acceSBarry Smith } 12079b94acceSBarry Smith 1208d25893d9SBarry Smith #undef __FUNCT__ 1209d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1210d25893d9SBarry Smith /*@C 1211d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1212d25893d9SBarry Smith 1213d25893d9SBarry Smith Logically Collective on SNES 1214d25893d9SBarry Smith 1215d25893d9SBarry Smith Input Parameters: 1216d25893d9SBarry Smith + snes - the SNES context 1217d25893d9SBarry Smith . func - function evaluation routine 1218d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1219d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1220d25893d9SBarry Smith 1221d25893d9SBarry Smith Calling sequence of func: 1222d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1223d25893d9SBarry Smith 1224d25893d9SBarry Smith . f - function vector 1225d25893d9SBarry Smith - ctx - optional user-defined function context 1226d25893d9SBarry Smith 1227d25893d9SBarry Smith Level: intermediate 1228d25893d9SBarry Smith 1229d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1230d25893d9SBarry Smith 1231d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1232d25893d9SBarry Smith @*/ 1233d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1234d25893d9SBarry Smith { 1235d25893d9SBarry Smith PetscFunctionBegin; 1236d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1237d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1238d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1239d25893d9SBarry Smith PetscFunctionReturn(0); 1240d25893d9SBarry Smith } 1241d25893d9SBarry Smith 12423ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 12433ab0aad5SBarry Smith #undef __FUNCT__ 12441096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 12451096aae1SMatthew Knepley /*@C 12461096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 12471096aae1SMatthew Knepley it assumes a zero right hand side. 12481096aae1SMatthew Knepley 12493f9fe445SBarry Smith Logically Collective on SNES 12501096aae1SMatthew Knepley 12511096aae1SMatthew Knepley Input Parameter: 12521096aae1SMatthew Knepley . snes - the SNES context 12531096aae1SMatthew Knepley 12541096aae1SMatthew Knepley Output Parameter: 1255bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 12561096aae1SMatthew Knepley 12571096aae1SMatthew Knepley Level: intermediate 12581096aae1SMatthew Knepley 12591096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 12601096aae1SMatthew Knepley 126185385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 12621096aae1SMatthew Knepley @*/ 12637087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 12641096aae1SMatthew Knepley { 12651096aae1SMatthew Knepley PetscFunctionBegin; 12660700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12671096aae1SMatthew Knepley PetscValidPointer(rhs,2); 126885385478SLisandro Dalcin *rhs = snes->vec_rhs; 12691096aae1SMatthew Knepley PetscFunctionReturn(0); 12701096aae1SMatthew Knepley } 12711096aae1SMatthew Knepley 12721096aae1SMatthew Knepley #undef __FUNCT__ 12734a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 12749b94acceSBarry Smith /*@ 127536851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 12769b94acceSBarry Smith SNESSetFunction(). 12779b94acceSBarry Smith 1278c7afd0dbSLois Curfman McInnes Collective on SNES 1279c7afd0dbSLois Curfman McInnes 12809b94acceSBarry Smith Input Parameters: 1281c7afd0dbSLois Curfman McInnes + snes - the SNES context 1282c7afd0dbSLois Curfman McInnes - x - input vector 12839b94acceSBarry Smith 12849b94acceSBarry Smith Output Parameter: 12853638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 12869b94acceSBarry Smith 12871bffabb2SLois Curfman McInnes Notes: 128836851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 128936851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 129036851e7fSLois Curfman McInnes themselves. 129136851e7fSLois Curfman McInnes 129236851e7fSLois Curfman McInnes Level: developer 129336851e7fSLois Curfman McInnes 12949b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 12959b94acceSBarry Smith 1296a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 12979b94acceSBarry Smith @*/ 12987087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 12999b94acceSBarry Smith { 1300dfbe8321SBarry Smith PetscErrorCode ierr; 13019b94acceSBarry Smith 13023a40ed3dSBarry Smith PetscFunctionBegin; 13030700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13040700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 13050700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1306c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1307c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 1308184914b5SBarry Smith 1309d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 1310e7788613SBarry Smith if (snes->ops->computefunction) { 1311d64ed03dSBarry Smith PetscStackPush("SNES user function"); 131239d508bbSBarry Smith ierr = (*snes->ops->computefunction)(snes,x,y,snes->funP);CHKERRQ(ierr); 1313d64ed03dSBarry Smith PetscStackPop; 131473250ac0SBarry Smith } else if (snes->dm) { 1315644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1316c90fad12SPeter Brune } else if (snes->vec_rhs) { 1317c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1318644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 131985385478SLisandro Dalcin if (snes->vec_rhs) { 132085385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 13213ab0aad5SBarry Smith } 1322ae3c334cSLois Curfman McInnes snes->nfuncs++; 1323d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 13243a40ed3dSBarry Smith PetscFunctionReturn(0); 13259b94acceSBarry Smith } 13269b94acceSBarry Smith 13274a2ae208SSatish Balay #undef __FUNCT__ 13284a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 132962fef451SLois Curfman McInnes /*@ 133062fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 133162fef451SLois Curfman McInnes set with SNESSetJacobian(). 133262fef451SLois Curfman McInnes 1333c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1334c7afd0dbSLois Curfman McInnes 133562fef451SLois Curfman McInnes Input Parameters: 1336c7afd0dbSLois Curfman McInnes + snes - the SNES context 1337c7afd0dbSLois Curfman McInnes - x - input vector 133862fef451SLois Curfman McInnes 133962fef451SLois Curfman McInnes Output Parameters: 1340c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 134162fef451SLois Curfman McInnes . B - optional preconditioning matrix 13422b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1343fee21e36SBarry Smith 1344e35cf81dSBarry Smith Options Database Keys: 1345e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1346693365a8SJed Brown . -snes_lag_jacobian <lag> 1347693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1348693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1349693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 1350693365a8SJed Brown - -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1351e35cf81dSBarry Smith 135262fef451SLois Curfman McInnes Notes: 135362fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 135462fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 135562fef451SLois Curfman McInnes 135694b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1357dc5a77f8SLois Curfman McInnes flag parameter. 135862fef451SLois Curfman McInnes 135936851e7fSLois Curfman McInnes Level: developer 136036851e7fSLois Curfman McInnes 136162fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 136262fef451SLois Curfman McInnes 1363e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 136462fef451SLois Curfman McInnes @*/ 13657087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 13669b94acceSBarry Smith { 1367dfbe8321SBarry Smith PetscErrorCode ierr; 1368ace3abfcSBarry Smith PetscBool flag; 13693a40ed3dSBarry Smith 13703a40ed3dSBarry Smith PetscFunctionBegin; 13710700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13720700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 13734482741eSBarry Smith PetscValidPointer(flg,5); 1374c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 1375e7788613SBarry Smith if (!snes->ops->computejacobian) PetscFunctionReturn(0); 1376ebd3b9afSBarry Smith 1377ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1378ebd3b9afSBarry Smith 1379fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 1380fe3ffe1eSBarry Smith snes->lagjacobian = -1; 1381fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1382fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 1383e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1384e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1385ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1386ebd3b9afSBarry Smith if (flag) { 1387ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1388ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1389ebd3b9afSBarry Smith } 1390e35cf81dSBarry Smith PetscFunctionReturn(0); 1391e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1392e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1393e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1394ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1395ebd3b9afSBarry Smith if (flag) { 1396ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1397ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1398ebd3b9afSBarry Smith } 1399e35cf81dSBarry Smith PetscFunctionReturn(0); 1400e35cf81dSBarry Smith } 1401e35cf81dSBarry Smith 1402c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 1403e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1404d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 1405e7788613SBarry Smith ierr = (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);CHKERRQ(ierr); 1406d64ed03dSBarry Smith PetscStackPop; 1407d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1408a8054027SBarry Smith 14093b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 14103b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 14113b4f5425SBarry Smith snes->lagpreconditioner = -1; 14123b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 1413a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1414a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 1415a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 1416a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1417a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 1418a8054027SBarry Smith } 1419a8054027SBarry Smith 14206d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 14210700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 14220700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 1423693365a8SJed Brown { 1424693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 1425693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 1426693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 1427693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 1428693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 1429693365a8SJed Brown if (flag || flag_draw || flag_contour) { 1430693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 1431693365a8SJed Brown MatStructure mstruct; 1432693365a8SJed Brown PetscViewer vdraw,vstdout; 14336b3a5b13SJed Brown PetscBool flg; 1434693365a8SJed Brown if (flag_operator) { 1435693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 1436693365a8SJed Brown Bexp = Bexp_mine; 1437693365a8SJed Brown } else { 1438693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 1439693365a8SJed Brown ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 1440693365a8SJed Brown if (flg) Bexp = *B; 1441693365a8SJed Brown else { 1442693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 1443693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 1444693365a8SJed Brown Bexp = Bexp_mine; 1445693365a8SJed Brown } 1446693365a8SJed Brown } 1447693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 1448693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 1449693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 1450693365a8SJed Brown if (flag_draw || flag_contour) { 1451693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 1452693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 1453693365a8SJed Brown } else vdraw = PETSC_NULL; 1454693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 1455693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 1456693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 1457693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 1458693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1459693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 1460693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1461693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 1462693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1463693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 1464693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 1465693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 1466693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 1467693365a8SJed Brown } 1468693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 1469693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 1470693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 1471693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 1472693365a8SJed Brown } 1473693365a8SJed Brown } 14743a40ed3dSBarry Smith PetscFunctionReturn(0); 14759b94acceSBarry Smith } 14769b94acceSBarry Smith 14774a2ae208SSatish Balay #undef __FUNCT__ 14784a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 14799b94acceSBarry Smith /*@C 14809b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 1481044dda88SLois Curfman McInnes location to store the matrix. 14829b94acceSBarry Smith 14833f9fe445SBarry Smith Logically Collective on SNES and Mat 1484c7afd0dbSLois Curfman McInnes 14859b94acceSBarry Smith Input Parameters: 1486c7afd0dbSLois Curfman McInnes + snes - the SNES context 14879b94acceSBarry Smith . A - Jacobian matrix 14889b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 1489efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 1490c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1491efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 14929b94acceSBarry Smith 14939b94acceSBarry Smith Calling sequence of func: 14948d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 14959b94acceSBarry Smith 1496c7afd0dbSLois Curfman McInnes + x - input vector 14979b94acceSBarry Smith . A - Jacobian matrix 14989b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 1499ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 15002b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 1501c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 15029b94acceSBarry Smith 15039b94acceSBarry Smith Notes: 150494b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 15052cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 1506ac21db08SLois Curfman McInnes 1507ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 15089b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 15099b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 15109b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 15119b94acceSBarry Smith throughout the global iterations. 15129b94acceSBarry Smith 151316913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 151416913363SBarry Smith each matrix. 151516913363SBarry Smith 1516a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 1517a8a26c1eSJed Brown must be a MatFDColoring. 1518a8a26c1eSJed Brown 1519c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 1520c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 1521c3cc8fd1SJed Brown 152236851e7fSLois Curfman McInnes Level: beginner 152336851e7fSLois Curfman McInnes 15249b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 15259b94acceSBarry Smith 15263ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 15279b94acceSBarry Smith @*/ 15287087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 15299b94acceSBarry Smith { 1530dfbe8321SBarry Smith PetscErrorCode ierr; 15313a7fca6bSBarry Smith 15323a40ed3dSBarry Smith PetscFunctionBegin; 15330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15340700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 15350700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 1536c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 153706975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 1538e7788613SBarry Smith if (func) snes->ops->computejacobian = func; 15393a7fca6bSBarry Smith if (ctx) snes->jacP = ctx; 15403a7fca6bSBarry Smith if (A) { 15417dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 15426bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 15439b94acceSBarry Smith snes->jacobian = A; 15443a7fca6bSBarry Smith } 15453a7fca6bSBarry Smith if (B) { 15467dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 15476bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 15489b94acceSBarry Smith snes->jacobian_pre = B; 15493a7fca6bSBarry Smith } 15503a40ed3dSBarry Smith PetscFunctionReturn(0); 15519b94acceSBarry Smith } 155262fef451SLois Curfman McInnes 15534a2ae208SSatish Balay #undef __FUNCT__ 15544a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 1555c2aafc4cSSatish Balay /*@C 1556b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 1557b4fd4287SBarry Smith provided context for evaluating the Jacobian. 1558b4fd4287SBarry Smith 1559c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 1560c7afd0dbSLois Curfman McInnes 1561b4fd4287SBarry Smith Input Parameter: 1562b4fd4287SBarry Smith . snes - the nonlinear solver context 1563b4fd4287SBarry Smith 1564b4fd4287SBarry Smith Output Parameters: 1565c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 1566b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 156770e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 156870e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 1569fee21e36SBarry Smith 157036851e7fSLois Curfman McInnes Level: advanced 157136851e7fSLois Curfman McInnes 1572b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 1573b4fd4287SBarry Smith @*/ 15747087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 1575b4fd4287SBarry Smith { 15763a40ed3dSBarry Smith PetscFunctionBegin; 15770700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1578b4fd4287SBarry Smith if (A) *A = snes->jacobian; 1579b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 1580e7788613SBarry Smith if (func) *func = snes->ops->computejacobian; 158170e92668SMatthew Knepley if (ctx) *ctx = snes->jacP; 15823a40ed3dSBarry Smith PetscFunctionReturn(0); 1583b4fd4287SBarry Smith } 1584b4fd4287SBarry Smith 15859b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 15869b94acceSBarry Smith 15874a2ae208SSatish Balay #undef __FUNCT__ 15884a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 15899b94acceSBarry Smith /*@ 15909b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 1591272ac6f2SLois Curfman McInnes of a nonlinear solver. 15929b94acceSBarry Smith 1593fee21e36SBarry Smith Collective on SNES 1594fee21e36SBarry Smith 1595c7afd0dbSLois Curfman McInnes Input Parameters: 159670e92668SMatthew Knepley . snes - the SNES context 1597c7afd0dbSLois Curfman McInnes 1598272ac6f2SLois Curfman McInnes Notes: 1599272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 1600272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 1601272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 1602272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 1603272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 1604272ac6f2SLois Curfman McInnes 160536851e7fSLois Curfman McInnes Level: advanced 160636851e7fSLois Curfman McInnes 16079b94acceSBarry Smith .keywords: SNES, nonlinear, setup 16089b94acceSBarry Smith 16099b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 16109b94acceSBarry Smith @*/ 16117087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 16129b94acceSBarry Smith { 1613dfbe8321SBarry Smith PetscErrorCode ierr; 16143a40ed3dSBarry Smith 16153a40ed3dSBarry Smith PetscFunctionBegin; 16160700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16174dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 16189b94acceSBarry Smith 16197adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 162085385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 162185385478SLisandro Dalcin } 162285385478SLisandro Dalcin 1623c9b9fda1SJed Brown if (!snes->vec_func) { 1624c9b9fda1SJed Brown if (snes->vec_rhs) { 1625c9b9fda1SJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 1626c9b9fda1SJed Brown } else if (snes->vec_sol) { 1627c9b9fda1SJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 1628c9b9fda1SJed Brown } else if (snes->dm) { 1629efd51863SBarry Smith ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 1630efd51863SBarry Smith } 1631c9b9fda1SJed Brown } 163217186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 163358c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 163458c9b817SLisandro Dalcin 163558c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 163658c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 163758c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 163858c9b817SLisandro Dalcin } 163958c9b817SLisandro Dalcin 1640ef8dffc7SBarry Smith if (!snes->ops->computejacobian && snes->dm) { 1641ef8dffc7SBarry Smith Mat J; 1642ef8dffc7SBarry Smith ierr = DMGetMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr); 1643cab2e9ccSBarry Smith ierr = SNESSetJacobian(snes,J,J,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr); 1644cab2e9ccSBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 16452ef29e96SBarry Smith } else if (!snes->jacobian && snes->ops->computejacobian == MatMFFDComputeJacobian) { 1646a8248277SBarry Smith Mat J; 1647a8248277SBarry Smith ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 1648a8248277SBarry Smith ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 1649a8248277SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 1650a8248277SBarry Smith ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);CHKERRQ(ierr); 1651a8248277SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 1652a8248277SBarry Smith } else if (snes->dm && snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 1653a8248277SBarry Smith Mat J,B; 1654a8248277SBarry Smith ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 1655a8248277SBarry Smith ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 1656a8248277SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 1657a8248277SBarry Smith ierr = DMGetMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 1658a8248277SBarry Smith ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,snes->funP);CHKERRQ(ierr); 1659a8248277SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 1660a8248277SBarry Smith ierr = MatDestroy(&B);CHKERRQ(ierr); 1661efd51863SBarry Smith } else if (snes->dm && !snes->jacobian_pre){ 1662efd51863SBarry Smith Mat J; 1663efd51863SBarry Smith ierr = DMGetMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr); 16643cbb28f5SBarry Smith ierr = SNESSetJacobian(snes,J,J,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1665efd51863SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 1666ef8dffc7SBarry Smith } 1667cfaf3a74SBarry Smith if (!snes->ops->computefunction && !snes->dm) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction() or call SNESSetDM()"); 1668c9b9fda1SJed Brown if (!snes->vec_func) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a vector when calling SNESSetFunction() or call SNESSetDM()"); 1669efd51863SBarry Smith 1670b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 1671b710008aSBarry Smith 1672d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 1673d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 1674d25893d9SBarry Smith } 1675d25893d9SBarry Smith 1676410397dcSLisandro Dalcin if (snes->ops->setup) { 1677410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 1678410397dcSLisandro Dalcin } 167958c9b817SLisandro Dalcin 16807aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 16813a40ed3dSBarry Smith PetscFunctionReturn(0); 16829b94acceSBarry Smith } 16839b94acceSBarry Smith 16844a2ae208SSatish Balay #undef __FUNCT__ 168537596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 168637596af1SLisandro Dalcin /*@ 168737596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 168837596af1SLisandro Dalcin 168937596af1SLisandro Dalcin Collective on SNES 169037596af1SLisandro Dalcin 169137596af1SLisandro Dalcin Input Parameter: 169237596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 169337596af1SLisandro Dalcin 1694d25893d9SBarry Smith Level: intermediate 1695d25893d9SBarry Smith 1696d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 169737596af1SLisandro Dalcin 169837596af1SLisandro Dalcin .keywords: SNES, destroy 169937596af1SLisandro Dalcin 170037596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 170137596af1SLisandro Dalcin @*/ 170237596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 170337596af1SLisandro Dalcin { 170437596af1SLisandro Dalcin PetscErrorCode ierr; 170537596af1SLisandro Dalcin 170637596af1SLisandro Dalcin PetscFunctionBegin; 170737596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1708d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 1709d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 1710d25893d9SBarry Smith snes->user = PETSC_NULL; 1711d25893d9SBarry Smith } 17128a23116dSBarry Smith if (snes->pc) { 17138a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 17148a23116dSBarry Smith } 17158a23116dSBarry Smith 171637596af1SLisandro Dalcin if (snes->ops->reset) { 171737596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 171837596af1SLisandro Dalcin } 171937596af1SLisandro Dalcin if (snes->ksp) {ierr = KSPReset(snes->ksp);CHKERRQ(ierr);} 17206bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 17216bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 17226bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 17236bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 17246bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 17256bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 172637596af1SLisandro Dalcin if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);} 172737596af1SLisandro Dalcin if (snes->vwork) {ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);} 172837596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 172937596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 173037596af1SLisandro Dalcin PetscFunctionReturn(0); 173137596af1SLisandro Dalcin } 173237596af1SLisandro Dalcin 173337596af1SLisandro Dalcin #undef __FUNCT__ 17344a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 173552baeb72SSatish Balay /*@ 17369b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 17379b94acceSBarry Smith with SNESCreate(). 17389b94acceSBarry Smith 1739c7afd0dbSLois Curfman McInnes Collective on SNES 1740c7afd0dbSLois Curfman McInnes 17419b94acceSBarry Smith Input Parameter: 17429b94acceSBarry Smith . snes - the SNES context 17439b94acceSBarry Smith 174436851e7fSLois Curfman McInnes Level: beginner 174536851e7fSLois Curfman McInnes 17469b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 17479b94acceSBarry Smith 174863a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 17499b94acceSBarry Smith @*/ 17506bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 17519b94acceSBarry Smith { 17526849ba73SBarry Smith PetscErrorCode ierr; 17533a40ed3dSBarry Smith 17543a40ed3dSBarry Smith PetscFunctionBegin; 17556bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 17566bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 17576bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 1758d4bb536fSBarry Smith 17596bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 17608a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 17616b8b9a38SLisandro Dalcin 1762be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 17636bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 17646bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 17656d4c513bSLisandro Dalcin 17666bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 17676bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 17686b8b9a38SLisandro Dalcin 17696bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 17706bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 17716bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 17726b8b9a38SLisandro Dalcin } 17736bf464f9SBarry Smith if ((*snes)->conv_malloc) { 17746bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 17756bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 177658c9b817SLisandro Dalcin } 1777ea630c6eSPeter Brune ierr = PetscViewerDestroy(&(*snes)->ls_monitor);CHKERRQ(ierr); 17786bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 1779a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 17803a40ed3dSBarry Smith PetscFunctionReturn(0); 17819b94acceSBarry Smith } 17829b94acceSBarry Smith 17839b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 17849b94acceSBarry Smith 17854a2ae208SSatish Balay #undef __FUNCT__ 1786a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 1787a8054027SBarry Smith /*@ 1788a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 1789a8054027SBarry Smith 17903f9fe445SBarry Smith Logically Collective on SNES 1791a8054027SBarry Smith 1792a8054027SBarry Smith Input Parameters: 1793a8054027SBarry Smith + snes - the SNES context 1794a8054027SBarry 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 17953b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 1796a8054027SBarry Smith 1797a8054027SBarry Smith Options Database Keys: 1798a8054027SBarry Smith . -snes_lag_preconditioner <lag> 1799a8054027SBarry Smith 1800a8054027SBarry Smith Notes: 1801a8054027SBarry Smith The default is 1 1802a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1803a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 1804a8054027SBarry Smith 1805a8054027SBarry Smith Level: intermediate 1806a8054027SBarry Smith 1807a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 1808a8054027SBarry Smith 1809e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 1810a8054027SBarry Smith 1811a8054027SBarry Smith @*/ 18127087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 1813a8054027SBarry Smith { 1814a8054027SBarry Smith PetscFunctionBegin; 18150700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1816e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 1817e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 1818c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 1819a8054027SBarry Smith snes->lagpreconditioner = lag; 1820a8054027SBarry Smith PetscFunctionReturn(0); 1821a8054027SBarry Smith } 1822a8054027SBarry Smith 1823a8054027SBarry Smith #undef __FUNCT__ 1824efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 1825efd51863SBarry Smith /*@ 1826efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 1827efd51863SBarry Smith 1828efd51863SBarry Smith Logically Collective on SNES 1829efd51863SBarry Smith 1830efd51863SBarry Smith Input Parameters: 1831efd51863SBarry Smith + snes - the SNES context 1832efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 1833efd51863SBarry Smith 1834efd51863SBarry Smith Options Database Keys: 1835efd51863SBarry Smith . -snes_grid_sequence <steps> 1836efd51863SBarry Smith 1837efd51863SBarry Smith Level: intermediate 1838efd51863SBarry Smith 1839efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 1840efd51863SBarry Smith 1841efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 1842efd51863SBarry Smith 1843efd51863SBarry Smith @*/ 1844efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 1845efd51863SBarry Smith { 1846efd51863SBarry Smith PetscFunctionBegin; 1847efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1848efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 1849efd51863SBarry Smith snes->gridsequence = steps; 1850efd51863SBarry Smith PetscFunctionReturn(0); 1851efd51863SBarry Smith } 1852efd51863SBarry Smith 1853efd51863SBarry Smith #undef __FUNCT__ 1854a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 1855a8054027SBarry Smith /*@ 1856a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 1857a8054027SBarry Smith 18583f9fe445SBarry Smith Not Collective 1859a8054027SBarry Smith 1860a8054027SBarry Smith Input Parameter: 1861a8054027SBarry Smith . snes - the SNES context 1862a8054027SBarry Smith 1863a8054027SBarry Smith Output Parameter: 1864a8054027SBarry 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 18653b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 1866a8054027SBarry Smith 1867a8054027SBarry Smith Options Database Keys: 1868a8054027SBarry Smith . -snes_lag_preconditioner <lag> 1869a8054027SBarry Smith 1870a8054027SBarry Smith Notes: 1871a8054027SBarry Smith The default is 1 1872a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1873a8054027SBarry Smith 1874a8054027SBarry Smith Level: intermediate 1875a8054027SBarry Smith 1876a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 1877a8054027SBarry Smith 1878a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 1879a8054027SBarry Smith 1880a8054027SBarry Smith @*/ 18817087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 1882a8054027SBarry Smith { 1883a8054027SBarry Smith PetscFunctionBegin; 18840700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1885a8054027SBarry Smith *lag = snes->lagpreconditioner; 1886a8054027SBarry Smith PetscFunctionReturn(0); 1887a8054027SBarry Smith } 1888a8054027SBarry Smith 1889a8054027SBarry Smith #undef __FUNCT__ 1890e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 1891e35cf81dSBarry Smith /*@ 1892e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 1893e35cf81dSBarry Smith often the preconditioner is rebuilt. 1894e35cf81dSBarry Smith 18953f9fe445SBarry Smith Logically Collective on SNES 1896e35cf81dSBarry Smith 1897e35cf81dSBarry Smith Input Parameters: 1898e35cf81dSBarry Smith + snes - the SNES context 1899e35cf81dSBarry 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 1900fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 1901e35cf81dSBarry Smith 1902e35cf81dSBarry Smith Options Database Keys: 1903e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 1904e35cf81dSBarry Smith 1905e35cf81dSBarry Smith Notes: 1906e35cf81dSBarry Smith The default is 1 1907e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1908fe3ffe1eSBarry 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 1909fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 1910e35cf81dSBarry Smith 1911e35cf81dSBarry Smith Level: intermediate 1912e35cf81dSBarry Smith 1913e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 1914e35cf81dSBarry Smith 1915e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 1916e35cf81dSBarry Smith 1917e35cf81dSBarry Smith @*/ 19187087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 1919e35cf81dSBarry Smith { 1920e35cf81dSBarry Smith PetscFunctionBegin; 19210700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1922e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 1923e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 1924c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 1925e35cf81dSBarry Smith snes->lagjacobian = lag; 1926e35cf81dSBarry Smith PetscFunctionReturn(0); 1927e35cf81dSBarry Smith } 1928e35cf81dSBarry Smith 1929e35cf81dSBarry Smith #undef __FUNCT__ 1930e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 1931e35cf81dSBarry Smith /*@ 1932e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 1933e35cf81dSBarry Smith 19343f9fe445SBarry Smith Not Collective 1935e35cf81dSBarry Smith 1936e35cf81dSBarry Smith Input Parameter: 1937e35cf81dSBarry Smith . snes - the SNES context 1938e35cf81dSBarry Smith 1939e35cf81dSBarry Smith Output Parameter: 1940e35cf81dSBarry 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 1941e35cf81dSBarry Smith the Jacobian is built etc. 1942e35cf81dSBarry Smith 1943e35cf81dSBarry Smith Options Database Keys: 1944e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 1945e35cf81dSBarry Smith 1946e35cf81dSBarry Smith Notes: 1947e35cf81dSBarry Smith The default is 1 1948e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1949e35cf81dSBarry Smith 1950e35cf81dSBarry Smith Level: intermediate 1951e35cf81dSBarry Smith 1952e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 1953e35cf81dSBarry Smith 1954e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 1955e35cf81dSBarry Smith 1956e35cf81dSBarry Smith @*/ 19577087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 1958e35cf81dSBarry Smith { 1959e35cf81dSBarry Smith PetscFunctionBegin; 19600700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1961e35cf81dSBarry Smith *lag = snes->lagjacobian; 1962e35cf81dSBarry Smith PetscFunctionReturn(0); 1963e35cf81dSBarry Smith } 1964e35cf81dSBarry Smith 1965e35cf81dSBarry Smith #undef __FUNCT__ 19664a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 19679b94acceSBarry Smith /*@ 1968d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 19699b94acceSBarry Smith 19703f9fe445SBarry Smith Logically Collective on SNES 1971c7afd0dbSLois Curfman McInnes 19729b94acceSBarry Smith Input Parameters: 1973c7afd0dbSLois Curfman McInnes + snes - the SNES context 197470441072SBarry Smith . abstol - absolute convergence tolerance 197533174efeSLois Curfman McInnes . rtol - relative convergence tolerance 197633174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 197733174efeSLois Curfman McInnes of the change in the solution between steps 197833174efeSLois Curfman McInnes . maxit - maximum number of iterations 1979c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 1980fee21e36SBarry Smith 198133174efeSLois Curfman McInnes Options Database Keys: 198270441072SBarry Smith + -snes_atol <abstol> - Sets abstol 1983c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 1984c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 1985c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 1986c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 19879b94acceSBarry Smith 1988d7a720efSLois Curfman McInnes Notes: 19899b94acceSBarry Smith The default maximum number of iterations is 50. 19909b94acceSBarry Smith The default maximum number of function evaluations is 1000. 19919b94acceSBarry Smith 199236851e7fSLois Curfman McInnes Level: intermediate 199336851e7fSLois Curfman McInnes 199433174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 19959b94acceSBarry Smith 19962492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 19979b94acceSBarry Smith @*/ 19987087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 19999b94acceSBarry Smith { 20003a40ed3dSBarry Smith PetscFunctionBegin; 20010700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2002c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2003c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2004c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2005c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2006c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2007c5eb9154SBarry Smith 2008ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2009ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2010ab54825eSJed Brown snes->abstol = abstol; 2011ab54825eSJed Brown } 2012ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2013ab54825eSJed 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); 2014ab54825eSJed Brown snes->rtol = rtol; 2015ab54825eSJed Brown } 2016ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2017ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2018ab54825eSJed Brown snes->xtol = stol; 2019ab54825eSJed Brown } 2020ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2021ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2022ab54825eSJed Brown snes->max_its = maxit; 2023ab54825eSJed Brown } 2024ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2025ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2026ab54825eSJed Brown snes->max_funcs = maxf; 2027ab54825eSJed Brown } 20283a40ed3dSBarry Smith PetscFunctionReturn(0); 20299b94acceSBarry Smith } 20309b94acceSBarry Smith 20314a2ae208SSatish Balay #undef __FUNCT__ 20324a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 20339b94acceSBarry Smith /*@ 203433174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 203533174efeSLois Curfman McInnes 2036c7afd0dbSLois Curfman McInnes Not Collective 2037c7afd0dbSLois Curfman McInnes 203833174efeSLois Curfman McInnes Input Parameters: 2039c7afd0dbSLois Curfman McInnes + snes - the SNES context 204085385478SLisandro Dalcin . atol - absolute convergence tolerance 204133174efeSLois Curfman McInnes . rtol - relative convergence tolerance 204233174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 204333174efeSLois Curfman McInnes of the change in the solution between steps 204433174efeSLois Curfman McInnes . maxit - maximum number of iterations 2045c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2046fee21e36SBarry Smith 204733174efeSLois Curfman McInnes Notes: 204833174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 204933174efeSLois Curfman McInnes 205036851e7fSLois Curfman McInnes Level: intermediate 205136851e7fSLois Curfman McInnes 205233174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 205333174efeSLois Curfman McInnes 205433174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 205533174efeSLois Curfman McInnes @*/ 20567087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 205733174efeSLois Curfman McInnes { 20583a40ed3dSBarry Smith PetscFunctionBegin; 20590700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 206085385478SLisandro Dalcin if (atol) *atol = snes->abstol; 206133174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 206233174efeSLois Curfman McInnes if (stol) *stol = snes->xtol; 206333174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 206433174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 20653a40ed3dSBarry Smith PetscFunctionReturn(0); 206633174efeSLois Curfman McInnes } 206733174efeSLois Curfman McInnes 20684a2ae208SSatish Balay #undef __FUNCT__ 20694a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 207033174efeSLois Curfman McInnes /*@ 20719b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 20729b94acceSBarry Smith 20733f9fe445SBarry Smith Logically Collective on SNES 2074fee21e36SBarry Smith 2075c7afd0dbSLois Curfman McInnes Input Parameters: 2076c7afd0dbSLois Curfman McInnes + snes - the SNES context 2077c7afd0dbSLois Curfman McInnes - tol - tolerance 2078c7afd0dbSLois Curfman McInnes 20799b94acceSBarry Smith Options Database Key: 2080c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 20819b94acceSBarry Smith 208236851e7fSLois Curfman McInnes Level: intermediate 208336851e7fSLois Curfman McInnes 20849b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 20859b94acceSBarry Smith 20862492ecdbSBarry Smith .seealso: SNESSetTolerances() 20879b94acceSBarry Smith @*/ 20887087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 20899b94acceSBarry Smith { 20903a40ed3dSBarry Smith PetscFunctionBegin; 20910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2092c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 20939b94acceSBarry Smith snes->deltatol = tol; 20943a40ed3dSBarry Smith PetscFunctionReturn(0); 20959b94acceSBarry Smith } 20969b94acceSBarry Smith 2097df9fa365SBarry Smith /* 2098df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2099df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2100df9fa365SBarry Smith macros instead of functions 2101df9fa365SBarry Smith */ 21024a2ae208SSatish Balay #undef __FUNCT__ 2103a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 21047087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2105ce1608b8SBarry Smith { 2106dfbe8321SBarry Smith PetscErrorCode ierr; 2107ce1608b8SBarry Smith 2108ce1608b8SBarry Smith PetscFunctionBegin; 21090700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2110a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2111ce1608b8SBarry Smith PetscFunctionReturn(0); 2112ce1608b8SBarry Smith } 2113ce1608b8SBarry Smith 21144a2ae208SSatish Balay #undef __FUNCT__ 2115a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 21167087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2117df9fa365SBarry Smith { 2118dfbe8321SBarry Smith PetscErrorCode ierr; 2119df9fa365SBarry Smith 2120df9fa365SBarry Smith PetscFunctionBegin; 2121a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2122df9fa365SBarry Smith PetscFunctionReturn(0); 2123df9fa365SBarry Smith } 2124df9fa365SBarry Smith 21254a2ae208SSatish Balay #undef __FUNCT__ 2126a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 21276bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2128df9fa365SBarry Smith { 2129dfbe8321SBarry Smith PetscErrorCode ierr; 2130df9fa365SBarry Smith 2131df9fa365SBarry Smith PetscFunctionBegin; 2132a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2133df9fa365SBarry Smith PetscFunctionReturn(0); 2134df9fa365SBarry Smith } 2135df9fa365SBarry Smith 21367087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2137b271bb04SBarry Smith #undef __FUNCT__ 2138b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 21397087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2140b271bb04SBarry Smith { 2141b271bb04SBarry Smith PetscDrawLG lg; 2142b271bb04SBarry Smith PetscErrorCode ierr; 2143b271bb04SBarry Smith PetscReal x,y,per; 2144b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2145b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2146b271bb04SBarry Smith PetscDraw draw; 2147b271bb04SBarry Smith PetscFunctionBegin; 2148b271bb04SBarry Smith if (!monctx) { 2149b271bb04SBarry Smith MPI_Comm comm; 2150b271bb04SBarry Smith 2151b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2152b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2153b271bb04SBarry Smith } 2154b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2155b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2156b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2157b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2158b271bb04SBarry Smith x = (PetscReal) n; 2159b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2160b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2161b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2162b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2163b271bb04SBarry Smith } 2164b271bb04SBarry Smith 2165b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2166b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2167b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2168b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2169b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2170b271bb04SBarry Smith x = (PetscReal) n; 2171b271bb04SBarry Smith y = 100.0*per; 2172b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2173b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2174b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2175b271bb04SBarry Smith } 2176b271bb04SBarry Smith 2177b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2178b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2179b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2180b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2181b271bb04SBarry Smith x = (PetscReal) n; 2182b271bb04SBarry Smith y = (prev - rnorm)/prev; 2183b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2184b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2185b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2186b271bb04SBarry Smith } 2187b271bb04SBarry Smith 2188b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2189b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2190b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2191b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2192b271bb04SBarry Smith x = (PetscReal) n; 2193b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2194b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2195b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2196b271bb04SBarry Smith } 2197b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2198b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2199b271bb04SBarry Smith } 2200b271bb04SBarry Smith prev = rnorm; 2201b271bb04SBarry Smith PetscFunctionReturn(0); 2202b271bb04SBarry Smith } 2203b271bb04SBarry Smith 2204b271bb04SBarry Smith #undef __FUNCT__ 2205b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 22067087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2207b271bb04SBarry Smith { 2208b271bb04SBarry Smith PetscErrorCode ierr; 2209b271bb04SBarry Smith 2210b271bb04SBarry Smith PetscFunctionBegin; 2211b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2212b271bb04SBarry Smith PetscFunctionReturn(0); 2213b271bb04SBarry Smith } 2214b271bb04SBarry Smith 2215b271bb04SBarry Smith #undef __FUNCT__ 2216b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 22176bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2218b271bb04SBarry Smith { 2219b271bb04SBarry Smith PetscErrorCode ierr; 2220b271bb04SBarry Smith 2221b271bb04SBarry Smith PetscFunctionBegin; 2222b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2223b271bb04SBarry Smith PetscFunctionReturn(0); 2224b271bb04SBarry Smith } 2225b271bb04SBarry Smith 22267a03ce2fSLisandro Dalcin #undef __FUNCT__ 22277a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 2228228d79bcSJed Brown /*@ 2229228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 2230228d79bcSJed Brown 2231228d79bcSJed Brown Collective on SNES 2232228d79bcSJed Brown 2233228d79bcSJed Brown Input Parameters: 2234228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 2235228d79bcSJed Brown . iter - iteration number 2236228d79bcSJed Brown - rnorm - relative norm of the residual 2237228d79bcSJed Brown 2238228d79bcSJed Brown Notes: 2239228d79bcSJed Brown This routine is called by the SNES implementations. 2240228d79bcSJed Brown It does not typically need to be called by the user. 2241228d79bcSJed Brown 2242228d79bcSJed Brown Level: developer 2243228d79bcSJed Brown 2244228d79bcSJed Brown .seealso: SNESMonitorSet() 2245228d79bcSJed Brown @*/ 22467a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 22477a03ce2fSLisandro Dalcin { 22487a03ce2fSLisandro Dalcin PetscErrorCode ierr; 22497a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 22507a03ce2fSLisandro Dalcin 22517a03ce2fSLisandro Dalcin PetscFunctionBegin; 22527a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 22537a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 22547a03ce2fSLisandro Dalcin } 22557a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 22567a03ce2fSLisandro Dalcin } 22577a03ce2fSLisandro Dalcin 22589b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 22599b94acceSBarry Smith 22604a2ae208SSatish Balay #undef __FUNCT__ 2261a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 22629b94acceSBarry Smith /*@C 2263a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 22649b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 22659b94acceSBarry Smith progress. 22669b94acceSBarry Smith 22673f9fe445SBarry Smith Logically Collective on SNES 2268fee21e36SBarry Smith 2269c7afd0dbSLois Curfman McInnes Input Parameters: 2270c7afd0dbSLois Curfman McInnes + snes - the SNES context 2271c7afd0dbSLois Curfman McInnes . func - monitoring routine 2272b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 2273e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 2274b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 2275b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 22769b94acceSBarry Smith 2277c7afd0dbSLois Curfman McInnes Calling sequence of func: 2278a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2279c7afd0dbSLois Curfman McInnes 2280c7afd0dbSLois Curfman McInnes + snes - the SNES context 2281c7afd0dbSLois Curfman McInnes . its - iteration number 2282c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 228340a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 22849b94acceSBarry Smith 22859665c990SLois Curfman McInnes Options Database Keys: 2286a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 2287a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 2288a6570f20SBarry Smith uses SNESMonitorLGCreate() 2289cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 2290c7afd0dbSLois Curfman McInnes been hardwired into a code by 2291a6570f20SBarry Smith calls to SNESMonitorSet(), but 2292c7afd0dbSLois Curfman McInnes does not cancel those set via 2293c7afd0dbSLois Curfman McInnes the options database. 22949665c990SLois Curfman McInnes 2295639f9d9dSBarry Smith Notes: 22966bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 2297a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 22986bc08f3fSLois Curfman McInnes order in which they were set. 2299639f9d9dSBarry Smith 2300025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 2301025f1a04SBarry Smith 230236851e7fSLois Curfman McInnes Level: intermediate 230336851e7fSLois Curfman McInnes 23049b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 23059b94acceSBarry Smith 2306a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 23079b94acceSBarry Smith @*/ 2308c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 23099b94acceSBarry Smith { 2310b90d0a6eSBarry Smith PetscInt i; 2311649052a6SBarry Smith PetscErrorCode ierr; 2312b90d0a6eSBarry Smith 23133a40ed3dSBarry Smith PetscFunctionBegin; 23140700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 231517186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2316b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 2317649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 2318649052a6SBarry Smith if (monitordestroy) { 2319c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 2320649052a6SBarry Smith } 2321b90d0a6eSBarry Smith PetscFunctionReturn(0); 2322b90d0a6eSBarry Smith } 2323b90d0a6eSBarry Smith } 2324b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 2325b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 2326639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 23273a40ed3dSBarry Smith PetscFunctionReturn(0); 23289b94acceSBarry Smith } 23299b94acceSBarry Smith 23304a2ae208SSatish Balay #undef __FUNCT__ 2331a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 23325cd90555SBarry Smith /*@C 2333a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 23345cd90555SBarry Smith 23353f9fe445SBarry Smith Logically Collective on SNES 2336c7afd0dbSLois Curfman McInnes 23375cd90555SBarry Smith Input Parameters: 23385cd90555SBarry Smith . snes - the SNES context 23395cd90555SBarry Smith 23401a480d89SAdministrator Options Database Key: 2341a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 2342a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 2343c7afd0dbSLois Curfman McInnes set via the options database 23445cd90555SBarry Smith 23455cd90555SBarry Smith Notes: 23465cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 23475cd90555SBarry Smith 234836851e7fSLois Curfman McInnes Level: intermediate 234936851e7fSLois Curfman McInnes 23505cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 23515cd90555SBarry Smith 2352a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 23535cd90555SBarry Smith @*/ 23547087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 23555cd90555SBarry Smith { 2356d952e501SBarry Smith PetscErrorCode ierr; 2357d952e501SBarry Smith PetscInt i; 2358d952e501SBarry Smith 23595cd90555SBarry Smith PetscFunctionBegin; 23600700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2361d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 2362d952e501SBarry Smith if (snes->monitordestroy[i]) { 23633c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 2364d952e501SBarry Smith } 2365d952e501SBarry Smith } 23665cd90555SBarry Smith snes->numbermonitors = 0; 23675cd90555SBarry Smith PetscFunctionReturn(0); 23685cd90555SBarry Smith } 23695cd90555SBarry Smith 23704a2ae208SSatish Balay #undef __FUNCT__ 23714a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 23729b94acceSBarry Smith /*@C 23739b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 23749b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 23759b94acceSBarry Smith 23763f9fe445SBarry Smith Logically Collective on SNES 2377fee21e36SBarry Smith 2378c7afd0dbSLois Curfman McInnes Input Parameters: 2379c7afd0dbSLois Curfman McInnes + snes - the SNES context 2380c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 23817f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 23827f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 23839b94acceSBarry Smith 2384c7afd0dbSLois Curfman McInnes Calling sequence of func: 238506ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 2386c7afd0dbSLois Curfman McInnes 2387c7afd0dbSLois Curfman McInnes + snes - the SNES context 238806ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 2389c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 2390184914b5SBarry Smith . reason - reason for convergence/divergence 2391c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 23924b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 23934b27c08aSLois Curfman McInnes - f - 2-norm of function 23949b94acceSBarry Smith 239536851e7fSLois Curfman McInnes Level: advanced 239636851e7fSLois Curfman McInnes 23979b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 23989b94acceSBarry Smith 239985385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 24009b94acceSBarry Smith @*/ 24017087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 24029b94acceSBarry Smith { 24037f7931b9SBarry Smith PetscErrorCode ierr; 24047f7931b9SBarry Smith 24053a40ed3dSBarry Smith PetscFunctionBegin; 24060700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 240785385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 24087f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 24097f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 24107f7931b9SBarry Smith } 241185385478SLisandro Dalcin snes->ops->converged = func; 24127f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 241385385478SLisandro Dalcin snes->cnvP = cctx; 24143a40ed3dSBarry Smith PetscFunctionReturn(0); 24159b94acceSBarry Smith } 24169b94acceSBarry Smith 24174a2ae208SSatish Balay #undef __FUNCT__ 24184a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 241952baeb72SSatish Balay /*@ 2420184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 2421184914b5SBarry Smith 2422184914b5SBarry Smith Not Collective 2423184914b5SBarry Smith 2424184914b5SBarry Smith Input Parameter: 2425184914b5SBarry Smith . snes - the SNES context 2426184914b5SBarry Smith 2427184914b5SBarry Smith Output Parameter: 24284d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 2429184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 2430184914b5SBarry Smith 2431184914b5SBarry Smith Level: intermediate 2432184914b5SBarry Smith 2433184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 2434184914b5SBarry Smith 2435184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 2436184914b5SBarry Smith 243785385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 2438184914b5SBarry Smith @*/ 24397087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 2440184914b5SBarry Smith { 2441184914b5SBarry Smith PetscFunctionBegin; 24420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 24434482741eSBarry Smith PetscValidPointer(reason,2); 2444184914b5SBarry Smith *reason = snes->reason; 2445184914b5SBarry Smith PetscFunctionReturn(0); 2446184914b5SBarry Smith } 2447184914b5SBarry Smith 24484a2ae208SSatish Balay #undef __FUNCT__ 24494a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 2450c9005455SLois Curfman McInnes /*@ 2451c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 2452c9005455SLois Curfman McInnes 24533f9fe445SBarry Smith Logically Collective on SNES 2454fee21e36SBarry Smith 2455c7afd0dbSLois Curfman McInnes Input Parameters: 2456c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 24578c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 2458cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 2459758f92a0SBarry Smith . na - size of a and its 246064731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 2461758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 2462c7afd0dbSLois Curfman McInnes 2463308dcc3eSBarry Smith Notes: 2464308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 2465308dcc3eSBarry Smith default array of length 10000 is allocated. 2466308dcc3eSBarry Smith 2467c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 2468c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 2469c9005455SLois Curfman McInnes during the section of code that is being timed. 2470c9005455SLois Curfman McInnes 247136851e7fSLois Curfman McInnes Level: intermediate 247236851e7fSLois Curfman McInnes 2473c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 2474758f92a0SBarry Smith 247508405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 2476758f92a0SBarry Smith 2477c9005455SLois Curfman McInnes @*/ 24787087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 2479c9005455SLois Curfman McInnes { 2480308dcc3eSBarry Smith PetscErrorCode ierr; 2481308dcc3eSBarry Smith 24823a40ed3dSBarry Smith PetscFunctionBegin; 24830700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 24844482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 2485a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 2486308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 2487308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 2488308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 2489308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 2490308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 2491308dcc3eSBarry Smith } 2492c9005455SLois Curfman McInnes snes->conv_hist = a; 2493758f92a0SBarry Smith snes->conv_hist_its = its; 2494758f92a0SBarry Smith snes->conv_hist_max = na; 2495a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 2496758f92a0SBarry Smith snes->conv_hist_reset = reset; 2497758f92a0SBarry Smith PetscFunctionReturn(0); 2498758f92a0SBarry Smith } 2499758f92a0SBarry Smith 2500308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 2501c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 2502c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 2503308dcc3eSBarry Smith EXTERN_C_BEGIN 2504308dcc3eSBarry Smith #undef __FUNCT__ 2505308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 2506308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 2507308dcc3eSBarry Smith { 2508308dcc3eSBarry Smith mxArray *mat; 2509308dcc3eSBarry Smith PetscInt i; 2510308dcc3eSBarry Smith PetscReal *ar; 2511308dcc3eSBarry Smith 2512308dcc3eSBarry Smith PetscFunctionBegin; 2513308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 2514308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 2515308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 2516308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 2517308dcc3eSBarry Smith } 2518308dcc3eSBarry Smith PetscFunctionReturn(mat); 2519308dcc3eSBarry Smith } 2520308dcc3eSBarry Smith EXTERN_C_END 2521308dcc3eSBarry Smith #endif 2522308dcc3eSBarry Smith 2523308dcc3eSBarry Smith 25244a2ae208SSatish Balay #undef __FUNCT__ 25254a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 25260c4c9dddSBarry Smith /*@C 2527758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 2528758f92a0SBarry Smith 25293f9fe445SBarry Smith Not Collective 2530758f92a0SBarry Smith 2531758f92a0SBarry Smith Input Parameter: 2532758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 2533758f92a0SBarry Smith 2534758f92a0SBarry Smith Output Parameters: 2535758f92a0SBarry Smith . a - array to hold history 2536758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 2537758f92a0SBarry Smith negative if not converged) for each solve. 2538758f92a0SBarry Smith - na - size of a and its 2539758f92a0SBarry Smith 2540758f92a0SBarry Smith Notes: 2541758f92a0SBarry Smith The calling sequence for this routine in Fortran is 2542758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 2543758f92a0SBarry Smith 2544758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 2545758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 2546758f92a0SBarry Smith during the section of code that is being timed. 2547758f92a0SBarry Smith 2548758f92a0SBarry Smith Level: intermediate 2549758f92a0SBarry Smith 2550758f92a0SBarry Smith .keywords: SNES, get, convergence, history 2551758f92a0SBarry Smith 2552758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 2553758f92a0SBarry Smith 2554758f92a0SBarry Smith @*/ 25557087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 2556758f92a0SBarry Smith { 2557758f92a0SBarry Smith PetscFunctionBegin; 25580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2559758f92a0SBarry Smith if (a) *a = snes->conv_hist; 2560758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 2561758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 25623a40ed3dSBarry Smith PetscFunctionReturn(0); 2563c9005455SLois Curfman McInnes } 2564c9005455SLois Curfman McInnes 2565e74ef692SMatthew Knepley #undef __FUNCT__ 2566e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 2567ac226902SBarry Smith /*@C 256876b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 2569eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 25707e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 257176b2cf59SMatthew Knepley 25723f9fe445SBarry Smith Logically Collective on SNES 257376b2cf59SMatthew Knepley 257476b2cf59SMatthew Knepley Input Parameters: 257576b2cf59SMatthew Knepley . snes - The nonlinear solver context 257676b2cf59SMatthew Knepley . func - The function 257776b2cf59SMatthew Knepley 257876b2cf59SMatthew Knepley Calling sequence of func: 2579b5d30489SBarry Smith . func (SNES snes, PetscInt step); 258076b2cf59SMatthew Knepley 258176b2cf59SMatthew Knepley . step - The current step of the iteration 258276b2cf59SMatthew Knepley 2583fe97e370SBarry Smith Level: advanced 2584fe97e370SBarry Smith 2585fe97e370SBarry 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() 2586fe97e370SBarry Smith This is not used by most users. 258776b2cf59SMatthew Knepley 258876b2cf59SMatthew Knepley .keywords: SNES, update 2589b5d30489SBarry Smith 259085385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 259176b2cf59SMatthew Knepley @*/ 25927087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 259376b2cf59SMatthew Knepley { 259476b2cf59SMatthew Knepley PetscFunctionBegin; 25950700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 2596e7788613SBarry Smith snes->ops->update = func; 259776b2cf59SMatthew Knepley PetscFunctionReturn(0); 259876b2cf59SMatthew Knepley } 259976b2cf59SMatthew Knepley 2600e74ef692SMatthew Knepley #undef __FUNCT__ 2601e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 260276b2cf59SMatthew Knepley /*@ 260376b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 260476b2cf59SMatthew Knepley 260576b2cf59SMatthew Knepley Not collective 260676b2cf59SMatthew Knepley 260776b2cf59SMatthew Knepley Input Parameters: 260876b2cf59SMatthew Knepley . snes - The nonlinear solver context 260976b2cf59SMatthew Knepley . step - The current step of the iteration 261076b2cf59SMatthew Knepley 2611205452f4SMatthew Knepley Level: intermediate 2612205452f4SMatthew Knepley 261376b2cf59SMatthew Knepley .keywords: SNES, update 2614a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 261576b2cf59SMatthew Knepley @*/ 26167087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 261776b2cf59SMatthew Knepley { 261876b2cf59SMatthew Knepley PetscFunctionBegin; 261976b2cf59SMatthew Knepley PetscFunctionReturn(0); 262076b2cf59SMatthew Knepley } 262176b2cf59SMatthew Knepley 26224a2ae208SSatish Balay #undef __FUNCT__ 26234a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 26249b94acceSBarry Smith /* 26259b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 26269b94acceSBarry Smith positive parameter delta. 26279b94acceSBarry Smith 26289b94acceSBarry Smith Input Parameters: 2629c7afd0dbSLois Curfman McInnes + snes - the SNES context 26309b94acceSBarry Smith . y - approximate solution of linear system 26319b94acceSBarry Smith . fnorm - 2-norm of current function 2632c7afd0dbSLois Curfman McInnes - delta - trust region size 26339b94acceSBarry Smith 26349b94acceSBarry Smith Output Parameters: 2635c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 26369b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 26379b94acceSBarry Smith region, and exceeds zero otherwise. 2638c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 26399b94acceSBarry Smith 26409b94acceSBarry Smith Note: 26414b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 26429b94acceSBarry Smith is set to be the maximum allowable step size. 26439b94acceSBarry Smith 26449b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 26459b94acceSBarry Smith */ 2646dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 26479b94acceSBarry Smith { 2648064f8208SBarry Smith PetscReal nrm; 2649ea709b57SSatish Balay PetscScalar cnorm; 2650dfbe8321SBarry Smith PetscErrorCode ierr; 26513a40ed3dSBarry Smith 26523a40ed3dSBarry Smith PetscFunctionBegin; 26530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 26540700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 2655c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 2656184914b5SBarry Smith 2657064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 2658064f8208SBarry Smith if (nrm > *delta) { 2659064f8208SBarry Smith nrm = *delta/nrm; 2660064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 2661064f8208SBarry Smith cnorm = nrm; 26622dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 26639b94acceSBarry Smith *ynorm = *delta; 26649b94acceSBarry Smith } else { 26659b94acceSBarry Smith *gpnorm = 0.0; 2666064f8208SBarry Smith *ynorm = nrm; 26679b94acceSBarry Smith } 26683a40ed3dSBarry Smith PetscFunctionReturn(0); 26699b94acceSBarry Smith } 26709b94acceSBarry Smith 26714a2ae208SSatish Balay #undef __FUNCT__ 26724a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 26736ce558aeSBarry Smith /*@C 2674f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 2675f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 26769b94acceSBarry Smith 2677c7afd0dbSLois Curfman McInnes Collective on SNES 2678c7afd0dbSLois Curfman McInnes 2679b2002411SLois Curfman McInnes Input Parameters: 2680c7afd0dbSLois Curfman McInnes + snes - the SNES context 26813cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 268285385478SLisandro Dalcin - x - the solution vector. 26839b94acceSBarry Smith 2684b2002411SLois Curfman McInnes Notes: 26858ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 26868ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 26878ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 26888ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 26898ddd3da0SLois Curfman McInnes 269036851e7fSLois Curfman McInnes Level: beginner 269136851e7fSLois Curfman McInnes 26929b94acceSBarry Smith .keywords: SNES, nonlinear, solve 26939b94acceSBarry Smith 269485385478SLisandro Dalcin .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian() 26959b94acceSBarry Smith @*/ 26967087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 26979b94acceSBarry Smith { 2698dfbe8321SBarry Smith PetscErrorCode ierr; 2699ace3abfcSBarry Smith PetscBool flg; 2700eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 2701eabae89aSBarry Smith PetscViewer viewer; 2702efd51863SBarry Smith PetscInt grid; 2703052efed2SBarry Smith 27043a40ed3dSBarry Smith PetscFunctionBegin; 27050700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 27060700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,3); 2707f69a0ea3SMatthew Knepley PetscCheckSameComm(snes,1,x,3); 27080700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 270985385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 271085385478SLisandro Dalcin 2711a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 2712efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 2713efd51863SBarry Smith 271485385478SLisandro Dalcin /* set solution vector */ 2715efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 27166bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 271785385478SLisandro Dalcin snes->vec_sol = x; 271885385478SLisandro Dalcin /* set afine vector if provided */ 271985385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 27206bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 272185385478SLisandro Dalcin snes->vec_rhs = b; 272285385478SLisandro Dalcin 272370e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 27243f149594SLisandro Dalcin 2725d25893d9SBarry Smith if (!grid && snes->ops->computeinitialguess) { 2726d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 2727d25893d9SBarry Smith } 2728d25893d9SBarry Smith 2729abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 273050ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 2731d5e45103SBarry Smith 27323f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 27334936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 273485385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 27354936397dSBarry Smith if (snes->domainerror){ 27364936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 27374936397dSBarry Smith snes->domainerror = PETSC_FALSE; 27384936397dSBarry Smith } 273917186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 27403f149594SLisandro Dalcin 27417adad957SLisandro Dalcin ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 2742eabae89aSBarry Smith if (flg && !PetscPreLoadingOn) { 27437adad957SLisandro Dalcin ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 2744eabae89aSBarry Smith ierr = SNESView(snes,viewer);CHKERRQ(ierr); 27456bf464f9SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 2746eabae89aSBarry Smith } 2747eabae89aSBarry Smith 274890d69ab7SBarry Smith flg = PETSC_FALSE; 2749acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 2750da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 27515968eb51SBarry Smith if (snes->printreason) { 2752a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 27535968eb51SBarry Smith if (snes->reason > 0) { 2754a8248277SBarry Smith ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 27555968eb51SBarry Smith } else { 2756a8248277SBarry Smith ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 27575968eb51SBarry Smith } 2758a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 27595968eb51SBarry Smith } 27605968eb51SBarry Smith 2761*8501fc72SJed Brown flg = PETSC_FALSE; 2762*8501fc72SJed Brown ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 2763*8501fc72SJed Brown if (flg) { 2764*8501fc72SJed Brown PetscViewer viewer; 2765*8501fc72SJed Brown ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 2766*8501fc72SJed Brown ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 2767*8501fc72SJed Brown ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 2768*8501fc72SJed Brown ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 2769*8501fc72SJed Brown ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 2770*8501fc72SJed Brown } 2771*8501fc72SJed Brown 2772e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 2773efd51863SBarry Smith if (grid < snes->gridsequence) { 2774efd51863SBarry Smith DM fine; 2775efd51863SBarry Smith Vec xnew; 2776efd51863SBarry Smith Mat interp; 2777efd51863SBarry Smith 2778efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 2779efd51863SBarry Smith ierr = DMGetInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 2780efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 2781efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 2782efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 2783efd51863SBarry Smith x = xnew; 2784efd51863SBarry Smith 2785efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 2786efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 2787efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 2788a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 2789efd51863SBarry Smith } 2790efd51863SBarry Smith } 27913a40ed3dSBarry Smith PetscFunctionReturn(0); 27929b94acceSBarry Smith } 27939b94acceSBarry Smith 27949b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 27959b94acceSBarry Smith 27964a2ae208SSatish Balay #undef __FUNCT__ 27974a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 279882bf6240SBarry Smith /*@C 27994b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 28009b94acceSBarry Smith 2801fee21e36SBarry Smith Collective on SNES 2802fee21e36SBarry Smith 2803c7afd0dbSLois Curfman McInnes Input Parameters: 2804c7afd0dbSLois Curfman McInnes + snes - the SNES context 2805454a90a3SBarry Smith - type - a known method 2806c7afd0dbSLois Curfman McInnes 2807c7afd0dbSLois Curfman McInnes Options Database Key: 2808454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 2809c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 2810ae12b187SLois Curfman McInnes 28119b94acceSBarry Smith Notes: 2812e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 28134b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 2814c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 28154b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 2816c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 28179b94acceSBarry Smith 2818ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 2819ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 2820ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 2821ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 2822ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 2823ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 2824ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 2825ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 2826ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 2827b0a32e0cSBarry Smith appropriate method. 282836851e7fSLois Curfman McInnes 282936851e7fSLois Curfman McInnes Level: intermediate 2830a703fe33SLois Curfman McInnes 2831454a90a3SBarry Smith .keywords: SNES, set, type 2832435da068SBarry Smith 2833435da068SBarry Smith .seealso: SNESType, SNESCreate() 2834435da068SBarry Smith 28359b94acceSBarry Smith @*/ 28367087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 28379b94acceSBarry Smith { 2838dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 2839ace3abfcSBarry Smith PetscBool match; 28403a40ed3dSBarry Smith 28413a40ed3dSBarry Smith PetscFunctionBegin; 28420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 28434482741eSBarry Smith PetscValidCharPointer(type,2); 284482bf6240SBarry Smith 28456831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 28460f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 284792ff6ae8SBarry Smith 28484b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 2849e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 285075396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 285175396ef9SLisandro Dalcin if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); } 285275396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 285375396ef9SLisandro Dalcin snes->ops->setup = 0; 285475396ef9SLisandro Dalcin snes->ops->solve = 0; 285575396ef9SLisandro Dalcin snes->ops->view = 0; 285675396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 285775396ef9SLisandro Dalcin snes->ops->destroy = 0; 285875396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 285975396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 2860454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 286103bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 28629fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 28639fb22e1aSBarry Smith if (PetscAMSPublishAll) { 28649fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 28659fb22e1aSBarry Smith } 28669fb22e1aSBarry Smith #endif 28673a40ed3dSBarry Smith PetscFunctionReturn(0); 28689b94acceSBarry Smith } 28699b94acceSBarry Smith 2870a847f771SSatish Balay 28719b94acceSBarry Smith /* --------------------------------------------------------------------- */ 28724a2ae208SSatish Balay #undef __FUNCT__ 28734a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 287452baeb72SSatish Balay /*@ 28759b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 2876f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 28779b94acceSBarry Smith 2878fee21e36SBarry Smith Not Collective 2879fee21e36SBarry Smith 288036851e7fSLois Curfman McInnes Level: advanced 288136851e7fSLois Curfman McInnes 28829b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 28839b94acceSBarry Smith 28849b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 28859b94acceSBarry Smith @*/ 28867087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 28879b94acceSBarry Smith { 2888dfbe8321SBarry Smith PetscErrorCode ierr; 288982bf6240SBarry Smith 28903a40ed3dSBarry Smith PetscFunctionBegin; 28911441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 28924c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 28933a40ed3dSBarry Smith PetscFunctionReturn(0); 28949b94acceSBarry Smith } 28959b94acceSBarry Smith 28964a2ae208SSatish Balay #undef __FUNCT__ 28974a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 28989b94acceSBarry Smith /*@C 28999a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 29009b94acceSBarry Smith 2901c7afd0dbSLois Curfman McInnes Not Collective 2902c7afd0dbSLois Curfman McInnes 29039b94acceSBarry Smith Input Parameter: 29044b0e389bSBarry Smith . snes - nonlinear solver context 29059b94acceSBarry Smith 29069b94acceSBarry Smith Output Parameter: 29073a7fca6bSBarry Smith . type - SNES method (a character string) 29089b94acceSBarry Smith 290936851e7fSLois Curfman McInnes Level: intermediate 291036851e7fSLois Curfman McInnes 2911454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 29129b94acceSBarry Smith @*/ 29137087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 29149b94acceSBarry Smith { 29153a40ed3dSBarry Smith PetscFunctionBegin; 29160700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 29174482741eSBarry Smith PetscValidPointer(type,2); 29187adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 29193a40ed3dSBarry Smith PetscFunctionReturn(0); 29209b94acceSBarry Smith } 29219b94acceSBarry Smith 29224a2ae208SSatish Balay #undef __FUNCT__ 29234a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 292452baeb72SSatish Balay /*@ 29259b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 29269b94acceSBarry Smith stored. 29279b94acceSBarry Smith 2928c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 2929c7afd0dbSLois Curfman McInnes 29309b94acceSBarry Smith Input Parameter: 29319b94acceSBarry Smith . snes - the SNES context 29329b94acceSBarry Smith 29339b94acceSBarry Smith Output Parameter: 29349b94acceSBarry Smith . x - the solution 29359b94acceSBarry Smith 293670e92668SMatthew Knepley Level: intermediate 293736851e7fSLois Curfman McInnes 29389b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 29399b94acceSBarry Smith 294085385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 29419b94acceSBarry Smith @*/ 29427087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 29439b94acceSBarry Smith { 29443a40ed3dSBarry Smith PetscFunctionBegin; 29450700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 29464482741eSBarry Smith PetscValidPointer(x,2); 294785385478SLisandro Dalcin *x = snes->vec_sol; 294870e92668SMatthew Knepley PetscFunctionReturn(0); 294970e92668SMatthew Knepley } 295070e92668SMatthew Knepley 295170e92668SMatthew Knepley #undef __FUNCT__ 29524a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 295352baeb72SSatish Balay /*@ 29549b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 29559b94acceSBarry Smith stored. 29569b94acceSBarry Smith 2957c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 2958c7afd0dbSLois Curfman McInnes 29599b94acceSBarry Smith Input Parameter: 29609b94acceSBarry Smith . snes - the SNES context 29619b94acceSBarry Smith 29629b94acceSBarry Smith Output Parameter: 29639b94acceSBarry Smith . x - the solution update 29649b94acceSBarry Smith 296536851e7fSLois Curfman McInnes Level: advanced 296636851e7fSLois Curfman McInnes 29679b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 29689b94acceSBarry Smith 296985385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 29709b94acceSBarry Smith @*/ 29717087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 29729b94acceSBarry Smith { 29733a40ed3dSBarry Smith PetscFunctionBegin; 29740700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 29754482741eSBarry Smith PetscValidPointer(x,2); 297685385478SLisandro Dalcin *x = snes->vec_sol_update; 29773a40ed3dSBarry Smith PetscFunctionReturn(0); 29789b94acceSBarry Smith } 29799b94acceSBarry Smith 29804a2ae208SSatish Balay #undef __FUNCT__ 29814a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 29829b94acceSBarry Smith /*@C 29833638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 29849b94acceSBarry Smith 2985c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 2986c7afd0dbSLois Curfman McInnes 29879b94acceSBarry Smith Input Parameter: 29889b94acceSBarry Smith . snes - the SNES context 29899b94acceSBarry Smith 29909b94acceSBarry Smith Output Parameter: 29917bf4e008SBarry Smith + r - the function (or PETSC_NULL) 299270e92668SMatthew Knepley . func - the function (or PETSC_NULL) 299370e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 29949b94acceSBarry Smith 299536851e7fSLois Curfman McInnes Level: advanced 299636851e7fSLois Curfman McInnes 2997a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 29989b94acceSBarry Smith 29994b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 30009b94acceSBarry Smith @*/ 30017087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 30029b94acceSBarry Smith { 30033a40ed3dSBarry Smith PetscFunctionBegin; 30040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 300585385478SLisandro Dalcin if (r) *r = snes->vec_func; 3006e7788613SBarry Smith if (func) *func = snes->ops->computefunction; 300770e92668SMatthew Knepley if (ctx) *ctx = snes->funP; 30083a40ed3dSBarry Smith PetscFunctionReturn(0); 30099b94acceSBarry Smith } 30109b94acceSBarry Smith 30114a2ae208SSatish Balay #undef __FUNCT__ 30124a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 30133c7409f5SSatish Balay /*@C 30143c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3015d850072dSLois Curfman McInnes SNES options in the database. 30163c7409f5SSatish Balay 30173f9fe445SBarry Smith Logically Collective on SNES 3018fee21e36SBarry Smith 3019c7afd0dbSLois Curfman McInnes Input Parameter: 3020c7afd0dbSLois Curfman McInnes + snes - the SNES context 3021c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3022c7afd0dbSLois Curfman McInnes 3023d850072dSLois Curfman McInnes Notes: 3024a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3025c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3026d850072dSLois Curfman McInnes 302736851e7fSLois Curfman McInnes Level: advanced 302836851e7fSLois Curfman McInnes 30293c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3030a86d99e1SLois Curfman McInnes 3031a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 30323c7409f5SSatish Balay @*/ 30337087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 30343c7409f5SSatish Balay { 3035dfbe8321SBarry Smith PetscErrorCode ierr; 30363c7409f5SSatish Balay 30373a40ed3dSBarry Smith PetscFunctionBegin; 30380700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3039639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 30401cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 304194b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 30423a40ed3dSBarry Smith PetscFunctionReturn(0); 30433c7409f5SSatish Balay } 30443c7409f5SSatish Balay 30454a2ae208SSatish Balay #undef __FUNCT__ 30464a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 30473c7409f5SSatish Balay /*@C 3048f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3049d850072dSLois Curfman McInnes SNES options in the database. 30503c7409f5SSatish Balay 30513f9fe445SBarry Smith Logically Collective on SNES 3052fee21e36SBarry Smith 3053c7afd0dbSLois Curfman McInnes Input Parameters: 3054c7afd0dbSLois Curfman McInnes + snes - the SNES context 3055c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3056c7afd0dbSLois Curfman McInnes 3057d850072dSLois Curfman McInnes Notes: 3058a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3059c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3060d850072dSLois Curfman McInnes 306136851e7fSLois Curfman McInnes Level: advanced 306236851e7fSLois Curfman McInnes 30633c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3064a86d99e1SLois Curfman McInnes 3065a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 30663c7409f5SSatish Balay @*/ 30677087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 30683c7409f5SSatish Balay { 3069dfbe8321SBarry Smith PetscErrorCode ierr; 30703c7409f5SSatish Balay 30713a40ed3dSBarry Smith PetscFunctionBegin; 30720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3073639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 30741cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 307594b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 30763a40ed3dSBarry Smith PetscFunctionReturn(0); 30773c7409f5SSatish Balay } 30783c7409f5SSatish Balay 30794a2ae208SSatish Balay #undef __FUNCT__ 30804a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 30819ab63eb5SSatish Balay /*@C 30823c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 30833c7409f5SSatish Balay SNES options in the database. 30843c7409f5SSatish Balay 3085c7afd0dbSLois Curfman McInnes Not Collective 3086c7afd0dbSLois Curfman McInnes 30873c7409f5SSatish Balay Input Parameter: 30883c7409f5SSatish Balay . snes - the SNES context 30893c7409f5SSatish Balay 30903c7409f5SSatish Balay Output Parameter: 30913c7409f5SSatish Balay . prefix - pointer to the prefix string used 30923c7409f5SSatish Balay 30934ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 30949ab63eb5SSatish Balay sufficient length to hold the prefix. 30959ab63eb5SSatish Balay 309636851e7fSLois Curfman McInnes Level: advanced 309736851e7fSLois Curfman McInnes 30983c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 3099a86d99e1SLois Curfman McInnes 3100a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 31013c7409f5SSatish Balay @*/ 31027087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 31033c7409f5SSatish Balay { 3104dfbe8321SBarry Smith PetscErrorCode ierr; 31053c7409f5SSatish Balay 31063a40ed3dSBarry Smith PetscFunctionBegin; 31070700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3108639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 31093a40ed3dSBarry Smith PetscFunctionReturn(0); 31103c7409f5SSatish Balay } 31113c7409f5SSatish Balay 3112b2002411SLois Curfman McInnes 31134a2ae208SSatish Balay #undef __FUNCT__ 31144a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 31153cea93caSBarry Smith /*@C 31163cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 31173cea93caSBarry Smith 31187f6c08e0SMatthew Knepley Level: advanced 31193cea93caSBarry Smith @*/ 31207087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3121b2002411SLois Curfman McInnes { 3122e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3123dfbe8321SBarry Smith PetscErrorCode ierr; 3124b2002411SLois Curfman McInnes 3125b2002411SLois Curfman McInnes PetscFunctionBegin; 3126b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3127c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3128b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3129b2002411SLois Curfman McInnes } 3130da9b6338SBarry Smith 3131da9b6338SBarry Smith #undef __FUNCT__ 3132da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 31337087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3134da9b6338SBarry Smith { 3135dfbe8321SBarry Smith PetscErrorCode ierr; 313677431f27SBarry Smith PetscInt N,i,j; 3137da9b6338SBarry Smith Vec u,uh,fh; 3138da9b6338SBarry Smith PetscScalar value; 3139da9b6338SBarry Smith PetscReal norm; 3140da9b6338SBarry Smith 3141da9b6338SBarry Smith PetscFunctionBegin; 3142da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3143da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3144da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3145da9b6338SBarry Smith 3146da9b6338SBarry Smith /* currently only works for sequential */ 3147da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3148da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3149da9b6338SBarry Smith for (i=0; i<N; i++) { 3150da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 315177431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3152da9b6338SBarry Smith for (j=-10; j<11; j++) { 3153ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3154da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 31553ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3156da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 315777431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3158da9b6338SBarry Smith value = -value; 3159da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3160da9b6338SBarry Smith } 3161da9b6338SBarry Smith } 31626bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 31636bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 3164da9b6338SBarry Smith PetscFunctionReturn(0); 3165da9b6338SBarry Smith } 316671f87433Sdalcinl 316771f87433Sdalcinl #undef __FUNCT__ 3168fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 316971f87433Sdalcinl /*@ 3170fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 317171f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 317271f87433Sdalcinl Newton method. 317371f87433Sdalcinl 31743f9fe445SBarry Smith Logically Collective on SNES 317571f87433Sdalcinl 317671f87433Sdalcinl Input Parameters: 317771f87433Sdalcinl + snes - SNES context 317871f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 317971f87433Sdalcinl 318064ba62caSBarry Smith Options Database: 318164ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 318264ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 318364ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 318464ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 318564ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 318664ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 318764ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 318864ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 318964ba62caSBarry Smith 319071f87433Sdalcinl Notes: 319171f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 319271f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 319371f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 319471f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 319571f87433Sdalcinl solver. 319671f87433Sdalcinl 319771f87433Sdalcinl Level: advanced 319871f87433Sdalcinl 319971f87433Sdalcinl Reference: 320071f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 320171f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 320271f87433Sdalcinl 320371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 320471f87433Sdalcinl 3205fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 320671f87433Sdalcinl @*/ 32077087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 320871f87433Sdalcinl { 320971f87433Sdalcinl PetscFunctionBegin; 32100700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3211acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 321271f87433Sdalcinl snes->ksp_ewconv = flag; 321371f87433Sdalcinl PetscFunctionReturn(0); 321471f87433Sdalcinl } 321571f87433Sdalcinl 321671f87433Sdalcinl #undef __FUNCT__ 3217fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 321871f87433Sdalcinl /*@ 3219fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 322071f87433Sdalcinl for computing relative tolerance for linear solvers within an 322171f87433Sdalcinl inexact Newton method. 322271f87433Sdalcinl 322371f87433Sdalcinl Not Collective 322471f87433Sdalcinl 322571f87433Sdalcinl Input Parameter: 322671f87433Sdalcinl . snes - SNES context 322771f87433Sdalcinl 322871f87433Sdalcinl Output Parameter: 322971f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 323071f87433Sdalcinl 323171f87433Sdalcinl Notes: 323271f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 323371f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 323471f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 323571f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 323671f87433Sdalcinl solver. 323771f87433Sdalcinl 323871f87433Sdalcinl Level: advanced 323971f87433Sdalcinl 324071f87433Sdalcinl Reference: 324171f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 324271f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 324371f87433Sdalcinl 324471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 324571f87433Sdalcinl 3246fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 324771f87433Sdalcinl @*/ 32487087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 324971f87433Sdalcinl { 325071f87433Sdalcinl PetscFunctionBegin; 32510700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 325271f87433Sdalcinl PetscValidPointer(flag,2); 325371f87433Sdalcinl *flag = snes->ksp_ewconv; 325471f87433Sdalcinl PetscFunctionReturn(0); 325571f87433Sdalcinl } 325671f87433Sdalcinl 325771f87433Sdalcinl #undef __FUNCT__ 3258fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 325971f87433Sdalcinl /*@ 3260fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 326171f87433Sdalcinl convergence criteria for the linear solvers within an inexact 326271f87433Sdalcinl Newton method. 326371f87433Sdalcinl 32643f9fe445SBarry Smith Logically Collective on SNES 326571f87433Sdalcinl 326671f87433Sdalcinl Input Parameters: 326771f87433Sdalcinl + snes - SNES context 326871f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 326971f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 327071f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 327171f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 327271f87433Sdalcinl (0 <= gamma2 <= 1) 327371f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 327471f87433Sdalcinl . alpha2 - power for safeguard 327571f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 327671f87433Sdalcinl 327771f87433Sdalcinl Note: 327871f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 327971f87433Sdalcinl 328071f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 328171f87433Sdalcinl 328271f87433Sdalcinl Level: advanced 328371f87433Sdalcinl 328471f87433Sdalcinl Reference: 328571f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 328671f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 328771f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 328871f87433Sdalcinl 328971f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 329071f87433Sdalcinl 3291fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 329271f87433Sdalcinl @*/ 32937087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 329471f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 329571f87433Sdalcinl { 3296fa9f3622SBarry Smith SNESKSPEW *kctx; 329771f87433Sdalcinl PetscFunctionBegin; 32980700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3299fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3300e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 3301c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 3302c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 3303c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 3304c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 3305c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 3306c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 3307c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 330871f87433Sdalcinl 330971f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 331071f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 331171f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 331271f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 331371f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 331471f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 331571f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 331671f87433Sdalcinl 331771f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 3318e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 331971f87433Sdalcinl } 332071f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 3321e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 332271f87433Sdalcinl } 332371f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 3324e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 332571f87433Sdalcinl } 332671f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 3327e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 332871f87433Sdalcinl } 332971f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 3330e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 333171f87433Sdalcinl } 333271f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 3333e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 333471f87433Sdalcinl } 333571f87433Sdalcinl PetscFunctionReturn(0); 333671f87433Sdalcinl } 333771f87433Sdalcinl 333871f87433Sdalcinl #undef __FUNCT__ 3339fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 334071f87433Sdalcinl /*@ 3341fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 334271f87433Sdalcinl convergence criteria for the linear solvers within an inexact 334371f87433Sdalcinl Newton method. 334471f87433Sdalcinl 334571f87433Sdalcinl Not Collective 334671f87433Sdalcinl 334771f87433Sdalcinl Input Parameters: 334871f87433Sdalcinl snes - SNES context 334971f87433Sdalcinl 335071f87433Sdalcinl Output Parameters: 335171f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 335271f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 335371f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 335471f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 335571f87433Sdalcinl (0 <= gamma2 <= 1) 335671f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 335771f87433Sdalcinl . alpha2 - power for safeguard 335871f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 335971f87433Sdalcinl 336071f87433Sdalcinl Level: advanced 336171f87433Sdalcinl 336271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 336371f87433Sdalcinl 3364fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 336571f87433Sdalcinl @*/ 33667087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 336771f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 336871f87433Sdalcinl { 3369fa9f3622SBarry Smith SNESKSPEW *kctx; 337071f87433Sdalcinl PetscFunctionBegin; 33710700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3372fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3373e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 337471f87433Sdalcinl if(version) *version = kctx->version; 337571f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 337671f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 337771f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 337871f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 337971f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 338071f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 338171f87433Sdalcinl PetscFunctionReturn(0); 338271f87433Sdalcinl } 338371f87433Sdalcinl 338471f87433Sdalcinl #undef __FUNCT__ 3385fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 3386fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 338771f87433Sdalcinl { 338871f87433Sdalcinl PetscErrorCode ierr; 3389fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 339071f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 339171f87433Sdalcinl 339271f87433Sdalcinl PetscFunctionBegin; 3393e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 339471f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 339571f87433Sdalcinl rtol = kctx->rtol_0; 339671f87433Sdalcinl } else { 339771f87433Sdalcinl if (kctx->version == 1) { 339871f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 339971f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 340071f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 340171f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 340271f87433Sdalcinl } else if (kctx->version == 2) { 340371f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 340471f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 340571f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 340671f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 340771f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 340871f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 340971f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 341071f87433Sdalcinl stol = PetscMax(rtol,stol); 341171f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 341271f87433Sdalcinl /* safeguard: avoid oversolving */ 341371f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 341471f87433Sdalcinl stol = PetscMax(rtol,stol); 341571f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 3416e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 341771f87433Sdalcinl } 341871f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 341971f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 342071f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 342171f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 342271f87433Sdalcinl PetscFunctionReturn(0); 342371f87433Sdalcinl } 342471f87433Sdalcinl 342571f87433Sdalcinl #undef __FUNCT__ 3426fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 3427fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 342871f87433Sdalcinl { 342971f87433Sdalcinl PetscErrorCode ierr; 3430fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 343171f87433Sdalcinl PCSide pcside; 343271f87433Sdalcinl Vec lres; 343371f87433Sdalcinl 343471f87433Sdalcinl PetscFunctionBegin; 3435e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 343671f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 343771f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 343871f87433Sdalcinl if (kctx->version == 1) { 3439b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 344071f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 344171f87433Sdalcinl /* KSP residual is true linear residual */ 344271f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 344371f87433Sdalcinl } else { 344471f87433Sdalcinl /* KSP residual is preconditioned residual */ 344571f87433Sdalcinl /* compute true linear residual norm */ 344671f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 344771f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 344871f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 344971f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 34506bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 345171f87433Sdalcinl } 345271f87433Sdalcinl } 345371f87433Sdalcinl PetscFunctionReturn(0); 345471f87433Sdalcinl } 345571f87433Sdalcinl 345671f87433Sdalcinl #undef __FUNCT__ 345771f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 345871f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 345971f87433Sdalcinl { 346071f87433Sdalcinl PetscErrorCode ierr; 346171f87433Sdalcinl 346271f87433Sdalcinl PetscFunctionBegin; 3463fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 346471f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 3465fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 346671f87433Sdalcinl PetscFunctionReturn(0); 346771f87433Sdalcinl } 34686c699258SBarry Smith 34696c699258SBarry Smith #undef __FUNCT__ 34706c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 34716c699258SBarry Smith /*@ 34726c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 34736c699258SBarry Smith 34743f9fe445SBarry Smith Logically Collective on SNES 34756c699258SBarry Smith 34766c699258SBarry Smith Input Parameters: 34776c699258SBarry Smith + snes - the preconditioner context 34786c699258SBarry Smith - dm - the dm 34796c699258SBarry Smith 34806c699258SBarry Smith Level: intermediate 34816c699258SBarry Smith 34826c699258SBarry Smith 34836c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 34846c699258SBarry Smith @*/ 34857087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 34866c699258SBarry Smith { 34876c699258SBarry Smith PetscErrorCode ierr; 3488345fed2cSBarry Smith KSP ksp; 34896c699258SBarry Smith 34906c699258SBarry Smith PetscFunctionBegin; 34910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3492d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 34936bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 34946c699258SBarry Smith snes->dm = dm; 3495345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 3496345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 3497f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 34982c155ee1SBarry Smith if (snes->pc) { 34992c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 35002c155ee1SBarry Smith } 35016c699258SBarry Smith PetscFunctionReturn(0); 35026c699258SBarry Smith } 35036c699258SBarry Smith 35046c699258SBarry Smith #undef __FUNCT__ 35056c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 35066c699258SBarry Smith /*@ 35076c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 35086c699258SBarry Smith 35093f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 35106c699258SBarry Smith 35116c699258SBarry Smith Input Parameter: 35126c699258SBarry Smith . snes - the preconditioner context 35136c699258SBarry Smith 35146c699258SBarry Smith Output Parameter: 35156c699258SBarry Smith . dm - the dm 35166c699258SBarry Smith 35176c699258SBarry Smith Level: intermediate 35186c699258SBarry Smith 35196c699258SBarry Smith 35206c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 35216c699258SBarry Smith @*/ 35227087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 35236c699258SBarry Smith { 35246c699258SBarry Smith PetscFunctionBegin; 35250700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35266c699258SBarry Smith *dm = snes->dm; 35276c699258SBarry Smith PetscFunctionReturn(0); 35286c699258SBarry Smith } 35290807856dSBarry Smith 353031823bd8SMatthew G Knepley #undef __FUNCT__ 353131823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 353231823bd8SMatthew G Knepley /*@ 3533fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 353431823bd8SMatthew G Knepley 353531823bd8SMatthew G Knepley Collective on SNES 353631823bd8SMatthew G Knepley 353731823bd8SMatthew G Knepley Input Parameters: 353831823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 353931823bd8SMatthew G Knepley - pc - the preconditioner object 354031823bd8SMatthew G Knepley 354131823bd8SMatthew G Knepley Notes: 354231823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 354331823bd8SMatthew G Knepley to configure it using the API). 354431823bd8SMatthew G Knepley 354531823bd8SMatthew G Knepley Level: developer 354631823bd8SMatthew G Knepley 354731823bd8SMatthew G Knepley .keywords: SNES, set, precondition 354831823bd8SMatthew G Knepley .seealso: SNESGetPC() 354931823bd8SMatthew G Knepley @*/ 355031823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 355131823bd8SMatthew G Knepley { 355231823bd8SMatthew G Knepley PetscErrorCode ierr; 355331823bd8SMatthew G Knepley 355431823bd8SMatthew G Knepley PetscFunctionBegin; 355531823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 355631823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 355731823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 355831823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 3559bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 356031823bd8SMatthew G Knepley snes->pc = pc; 356131823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 356231823bd8SMatthew G Knepley PetscFunctionReturn(0); 356331823bd8SMatthew G Knepley } 356431823bd8SMatthew G Knepley 356531823bd8SMatthew G Knepley #undef __FUNCT__ 356631823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 356731823bd8SMatthew G Knepley /*@ 3568fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 356931823bd8SMatthew G Knepley 357031823bd8SMatthew G Knepley Not Collective 357131823bd8SMatthew G Knepley 357231823bd8SMatthew G Knepley Input Parameter: 357331823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 357431823bd8SMatthew G Knepley 357531823bd8SMatthew G Knepley Output Parameter: 357631823bd8SMatthew G Knepley . pc - preconditioner context 357731823bd8SMatthew G Knepley 357831823bd8SMatthew G Knepley Level: developer 357931823bd8SMatthew G Knepley 358031823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 358131823bd8SMatthew G Knepley .seealso: SNESSetPC() 358231823bd8SMatthew G Knepley @*/ 358331823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 358431823bd8SMatthew G Knepley { 358531823bd8SMatthew G Knepley PetscErrorCode ierr; 358631823bd8SMatthew G Knepley 358731823bd8SMatthew G Knepley PetscFunctionBegin; 358831823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 358931823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 359031823bd8SMatthew G Knepley if (!snes->pc) { 359131823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr); 35924a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr); 359331823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 359431823bd8SMatthew G Knepley } 359531823bd8SMatthew G Knepley *pc = snes->pc; 359631823bd8SMatthew G Knepley PetscFunctionReturn(0); 359731823bd8SMatthew G Knepley } 359831823bd8SMatthew G Knepley 359969b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3600c6db04a5SJed Brown #include <mex.h> 360169b4f73cSBarry Smith 36028f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 36038f6e6473SBarry Smith 36040807856dSBarry Smith #undef __FUNCT__ 36050807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 36060807856dSBarry Smith /* 36070807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 36080807856dSBarry Smith SNESSetFunctionMatlab(). 36090807856dSBarry Smith 36100807856dSBarry Smith Collective on SNES 36110807856dSBarry Smith 36120807856dSBarry Smith Input Parameters: 36130807856dSBarry Smith + snes - the SNES context 36140807856dSBarry Smith - x - input vector 36150807856dSBarry Smith 36160807856dSBarry Smith Output Parameter: 36170807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 36180807856dSBarry Smith 36190807856dSBarry Smith Notes: 36200807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 36210807856dSBarry Smith implementations, so most users would not generally call this routine 36220807856dSBarry Smith themselves. 36230807856dSBarry Smith 36240807856dSBarry Smith Level: developer 36250807856dSBarry Smith 36260807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 36270807856dSBarry Smith 36280807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 362961b2408cSBarry Smith */ 36307087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 36310807856dSBarry Smith { 3632e650e774SBarry Smith PetscErrorCode ierr; 36338f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 36348f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 36358f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 363691621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 3637e650e774SBarry Smith 36380807856dSBarry Smith PetscFunctionBegin; 36390807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36400807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 36410807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 36420807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 36430807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 36440807856dSBarry Smith 36450807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 3646e650e774SBarry Smith 364791621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3648e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3649e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 365091621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 365191621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 365291621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 36538f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 36548f6e6473SBarry Smith prhs[4] = sctx->ctx; 3655b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 3656e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3657e650e774SBarry Smith mxDestroyArray(prhs[0]); 3658e650e774SBarry Smith mxDestroyArray(prhs[1]); 3659e650e774SBarry Smith mxDestroyArray(prhs[2]); 36608f6e6473SBarry Smith mxDestroyArray(prhs[3]); 3661e650e774SBarry Smith mxDestroyArray(plhs[0]); 36620807856dSBarry Smith PetscFunctionReturn(0); 36630807856dSBarry Smith } 36640807856dSBarry Smith 36650807856dSBarry Smith 36660807856dSBarry Smith #undef __FUNCT__ 36670807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 366861b2408cSBarry Smith /* 36690807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 36700807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 3671e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 36720807856dSBarry Smith 36730807856dSBarry Smith Logically Collective on SNES 36740807856dSBarry Smith 36750807856dSBarry Smith Input Parameters: 36760807856dSBarry Smith + snes - the SNES context 36770807856dSBarry Smith . r - vector to store function value 36780807856dSBarry Smith - func - function evaluation routine 36790807856dSBarry Smith 36800807856dSBarry Smith Calling sequence of func: 368161b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 36820807856dSBarry Smith 36830807856dSBarry Smith 36840807856dSBarry Smith Notes: 36850807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 36860807856dSBarry Smith $ f'(x) x = -f(x), 36870807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 36880807856dSBarry Smith 36890807856dSBarry Smith Level: beginner 36900807856dSBarry Smith 36910807856dSBarry Smith .keywords: SNES, nonlinear, set, function 36920807856dSBarry Smith 36930807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 369461b2408cSBarry Smith */ 36957087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 36960807856dSBarry Smith { 36970807856dSBarry Smith PetscErrorCode ierr; 36988f6e6473SBarry Smith SNESMatlabContext *sctx; 36990807856dSBarry Smith 37000807856dSBarry Smith PetscFunctionBegin; 37018f6e6473SBarry Smith /* currently sctx is memory bleed */ 37028f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 37038f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 37048f6e6473SBarry Smith /* 37058f6e6473SBarry Smith This should work, but it doesn't 37068f6e6473SBarry Smith sctx->ctx = ctx; 37078f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 37088f6e6473SBarry Smith */ 37098f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 37108f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 37110807856dSBarry Smith PetscFunctionReturn(0); 37120807856dSBarry Smith } 371369b4f73cSBarry Smith 371461b2408cSBarry Smith #undef __FUNCT__ 371561b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 371661b2408cSBarry Smith /* 371761b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 371861b2408cSBarry Smith SNESSetJacobianMatlab(). 371961b2408cSBarry Smith 372061b2408cSBarry Smith Collective on SNES 372161b2408cSBarry Smith 372261b2408cSBarry Smith Input Parameters: 372361b2408cSBarry Smith + snes - the SNES context 372461b2408cSBarry Smith . x - input vector 372561b2408cSBarry Smith . A, B - the matrices 372661b2408cSBarry Smith - ctx - user context 372761b2408cSBarry Smith 372861b2408cSBarry Smith Output Parameter: 372961b2408cSBarry Smith . flag - structure of the matrix 373061b2408cSBarry Smith 373161b2408cSBarry Smith Level: developer 373261b2408cSBarry Smith 373361b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 373461b2408cSBarry Smith 373561b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 373661b2408cSBarry Smith @*/ 37377087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 373861b2408cSBarry Smith { 373961b2408cSBarry Smith PetscErrorCode ierr; 374061b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 374161b2408cSBarry Smith int nlhs = 2,nrhs = 6; 374261b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 374361b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 374461b2408cSBarry Smith 374561b2408cSBarry Smith PetscFunctionBegin; 374661b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 374761b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 374861b2408cSBarry Smith 374961b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 375061b2408cSBarry Smith 375161b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 375261b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 375361b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 375461b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 375561b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 375661b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 375761b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 375861b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 375961b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 376061b2408cSBarry Smith prhs[5] = sctx->ctx; 3761b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 376261b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 376361b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 376461b2408cSBarry Smith mxDestroyArray(prhs[0]); 376561b2408cSBarry Smith mxDestroyArray(prhs[1]); 376661b2408cSBarry Smith mxDestroyArray(prhs[2]); 376761b2408cSBarry Smith mxDestroyArray(prhs[3]); 376861b2408cSBarry Smith mxDestroyArray(prhs[4]); 376961b2408cSBarry Smith mxDestroyArray(plhs[0]); 377061b2408cSBarry Smith mxDestroyArray(plhs[1]); 377161b2408cSBarry Smith PetscFunctionReturn(0); 377261b2408cSBarry Smith } 377361b2408cSBarry Smith 377461b2408cSBarry Smith 377561b2408cSBarry Smith #undef __FUNCT__ 377661b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 377761b2408cSBarry Smith /* 377861b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 377961b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 3780e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 378161b2408cSBarry Smith 378261b2408cSBarry Smith Logically Collective on SNES 378361b2408cSBarry Smith 378461b2408cSBarry Smith Input Parameters: 378561b2408cSBarry Smith + snes - the SNES context 378661b2408cSBarry Smith . A,B - Jacobian matrices 378761b2408cSBarry Smith . func - function evaluation routine 378861b2408cSBarry Smith - ctx - user context 378961b2408cSBarry Smith 379061b2408cSBarry Smith Calling sequence of func: 379161b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 379261b2408cSBarry Smith 379361b2408cSBarry Smith 379461b2408cSBarry Smith Level: developer 379561b2408cSBarry Smith 379661b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 379761b2408cSBarry Smith 379861b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 379961b2408cSBarry Smith */ 38007087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 380161b2408cSBarry Smith { 380261b2408cSBarry Smith PetscErrorCode ierr; 380361b2408cSBarry Smith SNESMatlabContext *sctx; 380461b2408cSBarry Smith 380561b2408cSBarry Smith PetscFunctionBegin; 380661b2408cSBarry Smith /* currently sctx is memory bleed */ 380761b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 380861b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 380961b2408cSBarry Smith /* 381061b2408cSBarry Smith This should work, but it doesn't 381161b2408cSBarry Smith sctx->ctx = ctx; 381261b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 381361b2408cSBarry Smith */ 381461b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 381561b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 381661b2408cSBarry Smith PetscFunctionReturn(0); 381761b2408cSBarry Smith } 381869b4f73cSBarry Smith 3819f9eb7ae2SShri Abhyankar #undef __FUNCT__ 3820f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 3821f9eb7ae2SShri Abhyankar /* 3822f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 3823f9eb7ae2SShri Abhyankar 3824f9eb7ae2SShri Abhyankar Collective on SNES 3825f9eb7ae2SShri Abhyankar 3826f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 3827f9eb7ae2SShri Abhyankar @*/ 38287087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 3829f9eb7ae2SShri Abhyankar { 3830f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 383148f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3832f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 3833f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 3834f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 3835f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 3836f9eb7ae2SShri Abhyankar 3837f9eb7ae2SShri Abhyankar PetscFunctionBegin; 3838f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3839f9eb7ae2SShri Abhyankar 3840f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3841f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3842f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 3843f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 3844f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 3845f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 3846f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 3847f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 3848f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 3849f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3850f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 3851f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 3852f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 3853f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 3854f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 3855f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 3856f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 3857f9eb7ae2SShri Abhyankar } 3858f9eb7ae2SShri Abhyankar 3859f9eb7ae2SShri Abhyankar 3860f9eb7ae2SShri Abhyankar #undef __FUNCT__ 3861f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 3862f9eb7ae2SShri Abhyankar /* 3863e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 3864f9eb7ae2SShri Abhyankar 3865f9eb7ae2SShri Abhyankar Level: developer 3866f9eb7ae2SShri Abhyankar 3867f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 3868f9eb7ae2SShri Abhyankar 3869f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3870f9eb7ae2SShri Abhyankar */ 38717087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 3872f9eb7ae2SShri Abhyankar { 3873f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 3874f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 3875f9eb7ae2SShri Abhyankar 3876f9eb7ae2SShri Abhyankar PetscFunctionBegin; 3877f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 3878f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3879f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3880f9eb7ae2SShri Abhyankar /* 3881f9eb7ae2SShri Abhyankar This should work, but it doesn't 3882f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 3883f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 3884f9eb7ae2SShri Abhyankar */ 3885f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 3886f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 3887f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 3888f9eb7ae2SShri Abhyankar } 3889f9eb7ae2SShri Abhyankar 389069b4f73cSBarry Smith #endif 3891