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 315*4839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 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); 498af60355fSPeter Brune ierr = PetscOptionsInt("-snes_ls_it" ,"Line search iterations","SNES",snes->ls_its,&snes->ls_its,&flg);CHKERRQ(ierr); 499ea630c6eSPeter Brune ierr = PetscOptionsBool("-snes_ls_monitor","Print progress of line searches","SNESLineSearchSetMonitor",snes->ls_monitor ? PETSC_TRUE : PETSC_FALSE,&flg,&set);CHKERRQ(ierr); 500ea630c6eSPeter Brune if (set) {ierr = SNESLineSearchSetMonitor(snes,flg);CHKERRQ(ierr);} 50115f5eeeaSPeter Brune ierr = PetscOptionsEnum("-snes_ls","Line search used","SNESLineSearchSet",SNESLineSearchTypes,(PetscEnum)snes->ls_type,(PetscEnum*)&indx,&flg);CHKERRQ(ierr); 50215f5eeeaSPeter Brune if (flg) { 503ea630c6eSPeter Brune ierr = SNESLineSearchSetType(snes,(SNESLineSearchType)indx);CHKERRQ(ierr); 50415f5eeeaSPeter Brune } 5058e3fc8c0SJed Brown flg = snes->ops->precheckstep == SNESLineSearchPreCheckPicard ? PETSC_TRUE : PETSC_FALSE; 5068e3fc8c0SJed Brown ierr = PetscOptionsBool("-snes_ls_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);CHKERRQ(ierr); 5078e3fc8c0SJed Brown if (set) { 5088e3fc8c0SJed Brown if (flg) { 5098e3fc8c0SJed Brown snes->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */ 5108e3fc8c0SJed 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); 5118e3fc8c0SJed Brown ierr = SNESLineSearchSetPreCheck(snes,SNESLineSearchPreCheckPicard,&snes->precheck_picard_angle);CHKERRQ(ierr); 5128e3fc8c0SJed Brown } else { 5138e3fc8c0SJed Brown ierr = SNESLineSearchSetPreCheck(snes,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 5148e3fc8c0SJed Brown } 5158e3fc8c0SJed Brown } 5168e3fc8c0SJed Brown 51776b2cf59SMatthew Knepley for(i = 0; i < numberofsetfromoptions; i++) { 51876b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 51976b2cf59SMatthew Knepley } 52076b2cf59SMatthew Knepley 521e7788613SBarry Smith if (snes->ops->setfromoptions) { 522e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 523639f9d9dSBarry Smith } 5245d973c19SBarry Smith 5255d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 5265d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 527b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 5284bbc92c1SBarry Smith 529aa3661deSLisandro Dalcin if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 5301cee3971SBarry Smith 5311cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 532aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 533aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 53485385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 53593993e2dSLois Curfman McInnes 53651e86f29SPeter Brune /* if someone has set the SNES PC type, create it. */ 53751e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 53851e86f29SPeter Brune ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 53951e86f29SPeter Brune if (pcset && (!snes->pc)) { 54051e86f29SPeter Brune ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr); 54151e86f29SPeter Brune } 54251e86f29SPeter Brune 5434a0c5b0cSMatthew G Knepley if (snes->pc) { 5444a0c5b0cSMatthew G Knepley ierr = SNESSetOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr); 5454a0c5b0cSMatthew G Knepley ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 546646217ecSPeter Brune ierr = SNESSetGS(snes->pc, snes->ops->computegs, snes->gsP);CHKERRQ(ierr); 5474a0c5b0cSMatthew G Knepley /* Should we make a duplicate vector and matrix? Leave the DM to make it? */ 5484a0c5b0cSMatthew G Knepley ierr = SNESSetFunction(snes->pc, snes->vec_func, snes->ops->computefunction, snes->funP);CHKERRQ(ierr); 5494a0c5b0cSMatthew G Knepley ierr = SNESSetJacobian(snes->pc, snes->jacobian, snes->jacobian_pre, snes->ops->computejacobian, snes->jacP);CHKERRQ(ierr); 5504a0c5b0cSMatthew G Knepley ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 5514a0c5b0cSMatthew G Knepley } 5523a40ed3dSBarry Smith PetscFunctionReturn(0); 5539b94acceSBarry Smith } 5549b94acceSBarry Smith 555d25893d9SBarry Smith #undef __FUNCT__ 556d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 557d25893d9SBarry Smith /*@ 558d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 559d25893d9SBarry Smith the nonlinear solvers. 560d25893d9SBarry Smith 561d25893d9SBarry Smith Logically Collective on SNES 562d25893d9SBarry Smith 563d25893d9SBarry Smith Input Parameters: 564d25893d9SBarry Smith + snes - the SNES context 565d25893d9SBarry Smith . compute - function to compute the context 566d25893d9SBarry Smith - destroy - function to destroy the context 567d25893d9SBarry Smith 568d25893d9SBarry Smith Level: intermediate 569d25893d9SBarry Smith 570d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 571d25893d9SBarry Smith 572d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 573d25893d9SBarry Smith @*/ 574d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 575d25893d9SBarry Smith { 576d25893d9SBarry Smith PetscFunctionBegin; 577d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 578d25893d9SBarry Smith snes->ops->usercompute = compute; 579d25893d9SBarry Smith snes->ops->userdestroy = destroy; 580d25893d9SBarry Smith PetscFunctionReturn(0); 581d25893d9SBarry Smith } 582a847f771SSatish Balay 5834a2ae208SSatish Balay #undef __FUNCT__ 5844a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 585b07ff414SBarry Smith /*@ 5869b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 5879b94acceSBarry Smith the nonlinear solvers. 5889b94acceSBarry Smith 5893f9fe445SBarry Smith Logically Collective on SNES 590fee21e36SBarry Smith 591c7afd0dbSLois Curfman McInnes Input Parameters: 592c7afd0dbSLois Curfman McInnes + snes - the SNES context 593c7afd0dbSLois Curfman McInnes - usrP - optional user context 594c7afd0dbSLois Curfman McInnes 59536851e7fSLois Curfman McInnes Level: intermediate 59636851e7fSLois Curfman McInnes 5979b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 5989b94acceSBarry Smith 599d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext() 6009b94acceSBarry Smith @*/ 6017087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 6029b94acceSBarry Smith { 6031b2093e4SBarry Smith PetscErrorCode ierr; 604b07ff414SBarry Smith KSP ksp; 6051b2093e4SBarry Smith 6063a40ed3dSBarry Smith PetscFunctionBegin; 6070700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 608b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 609b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 6109b94acceSBarry Smith snes->user = usrP; 6113a40ed3dSBarry Smith PetscFunctionReturn(0); 6129b94acceSBarry Smith } 61374679c65SBarry Smith 6144a2ae208SSatish Balay #undef __FUNCT__ 6154a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 616b07ff414SBarry Smith /*@ 6179b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 6189b94acceSBarry Smith nonlinear solvers. 6199b94acceSBarry Smith 620c7afd0dbSLois Curfman McInnes Not Collective 621c7afd0dbSLois Curfman McInnes 6229b94acceSBarry Smith Input Parameter: 6239b94acceSBarry Smith . snes - SNES context 6249b94acceSBarry Smith 6259b94acceSBarry Smith Output Parameter: 6269b94acceSBarry Smith . usrP - user context 6279b94acceSBarry Smith 62836851e7fSLois Curfman McInnes Level: intermediate 62936851e7fSLois Curfman McInnes 6309b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 6319b94acceSBarry Smith 6329b94acceSBarry Smith .seealso: SNESSetApplicationContext() 6339b94acceSBarry Smith @*/ 634e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 6359b94acceSBarry Smith { 6363a40ed3dSBarry Smith PetscFunctionBegin; 6370700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 638e71120c6SJed Brown *(void**)usrP = snes->user; 6393a40ed3dSBarry Smith PetscFunctionReturn(0); 6409b94acceSBarry Smith } 64174679c65SBarry Smith 6424a2ae208SSatish Balay #undef __FUNCT__ 6434a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 6449b94acceSBarry Smith /*@ 645c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 646c8228a4eSBarry Smith at this time. 6479b94acceSBarry Smith 648c7afd0dbSLois Curfman McInnes Not Collective 649c7afd0dbSLois Curfman McInnes 6509b94acceSBarry Smith Input Parameter: 6519b94acceSBarry Smith . snes - SNES context 6529b94acceSBarry Smith 6539b94acceSBarry Smith Output Parameter: 6549b94acceSBarry Smith . iter - iteration number 6559b94acceSBarry Smith 656c8228a4eSBarry Smith Notes: 657c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 658c8228a4eSBarry Smith 659c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 66008405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 66108405cd6SLois Curfman McInnes .vb 66208405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 66308405cd6SLois Curfman McInnes if (!(it % 2)) { 66408405cd6SLois Curfman McInnes [compute Jacobian here] 66508405cd6SLois Curfman McInnes } 66608405cd6SLois Curfman McInnes .ve 667c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 66808405cd6SLois Curfman McInnes recomputed every second SNES iteration. 669c8228a4eSBarry Smith 67036851e7fSLois Curfman McInnes Level: intermediate 67136851e7fSLois Curfman McInnes 6722b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 6732b668275SBarry Smith 674b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 6759b94acceSBarry Smith @*/ 6767087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 6779b94acceSBarry Smith { 6783a40ed3dSBarry Smith PetscFunctionBegin; 6790700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 6804482741eSBarry Smith PetscValidIntPointer(iter,2); 6819b94acceSBarry Smith *iter = snes->iter; 6823a40ed3dSBarry Smith PetscFunctionReturn(0); 6839b94acceSBarry Smith } 68474679c65SBarry Smith 6854a2ae208SSatish Balay #undef __FUNCT__ 6864a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 6879b94acceSBarry Smith /*@ 6889b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 6899b94acceSBarry Smith with SNESSSetFunction(). 6909b94acceSBarry Smith 691c7afd0dbSLois Curfman McInnes Collective on SNES 692c7afd0dbSLois Curfman McInnes 6939b94acceSBarry Smith Input Parameter: 6949b94acceSBarry Smith . snes - SNES context 6959b94acceSBarry Smith 6969b94acceSBarry Smith Output Parameter: 6979b94acceSBarry Smith . fnorm - 2-norm of function 6989b94acceSBarry Smith 69936851e7fSLois Curfman McInnes Level: intermediate 70036851e7fSLois Curfman McInnes 7019b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 702a86d99e1SLois Curfman McInnes 703b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 7049b94acceSBarry Smith @*/ 7057087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 7069b94acceSBarry Smith { 7073a40ed3dSBarry Smith PetscFunctionBegin; 7080700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7094482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 7109b94acceSBarry Smith *fnorm = snes->norm; 7113a40ed3dSBarry Smith PetscFunctionReturn(0); 7129b94acceSBarry Smith } 71374679c65SBarry Smith 7144a2ae208SSatish Balay #undef __FUNCT__ 715b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 7169b94acceSBarry Smith /*@ 717b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 7189b94acceSBarry Smith attempted by the nonlinear solver. 7199b94acceSBarry Smith 720c7afd0dbSLois Curfman McInnes Not Collective 721c7afd0dbSLois Curfman McInnes 7229b94acceSBarry Smith Input Parameter: 7239b94acceSBarry Smith . snes - SNES context 7249b94acceSBarry Smith 7259b94acceSBarry Smith Output Parameter: 7269b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 7279b94acceSBarry Smith 728c96a6f78SLois Curfman McInnes Notes: 729c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 730c96a6f78SLois Curfman McInnes 73136851e7fSLois Curfman McInnes Level: intermediate 73236851e7fSLois Curfman McInnes 7339b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 73458ebbce7SBarry Smith 735e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 73658ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 7379b94acceSBarry Smith @*/ 7387087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 7399b94acceSBarry Smith { 7403a40ed3dSBarry Smith PetscFunctionBegin; 7410700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7424482741eSBarry Smith PetscValidIntPointer(nfails,2); 74350ffb88aSMatthew Knepley *nfails = snes->numFailures; 74450ffb88aSMatthew Knepley PetscFunctionReturn(0); 74550ffb88aSMatthew Knepley } 74650ffb88aSMatthew Knepley 74750ffb88aSMatthew Knepley #undef __FUNCT__ 748b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 74950ffb88aSMatthew Knepley /*@ 750b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 75150ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 75250ffb88aSMatthew Knepley 75350ffb88aSMatthew Knepley Not Collective 75450ffb88aSMatthew Knepley 75550ffb88aSMatthew Knepley Input Parameters: 75650ffb88aSMatthew Knepley + snes - SNES context 75750ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 75850ffb88aSMatthew Knepley 75950ffb88aSMatthew Knepley Level: intermediate 76050ffb88aSMatthew Knepley 76150ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 76258ebbce7SBarry Smith 763e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 76458ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 76550ffb88aSMatthew Knepley @*/ 7667087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 76750ffb88aSMatthew Knepley { 76850ffb88aSMatthew Knepley PetscFunctionBegin; 7690700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 77050ffb88aSMatthew Knepley snes->maxFailures = maxFails; 77150ffb88aSMatthew Knepley PetscFunctionReturn(0); 77250ffb88aSMatthew Knepley } 77350ffb88aSMatthew Knepley 77450ffb88aSMatthew Knepley #undef __FUNCT__ 775b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 77650ffb88aSMatthew Knepley /*@ 777b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 77850ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 77950ffb88aSMatthew Knepley 78050ffb88aSMatthew Knepley Not Collective 78150ffb88aSMatthew Knepley 78250ffb88aSMatthew Knepley Input Parameter: 78350ffb88aSMatthew Knepley . snes - SNES context 78450ffb88aSMatthew Knepley 78550ffb88aSMatthew Knepley Output Parameter: 78650ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 78750ffb88aSMatthew Knepley 78850ffb88aSMatthew Knepley Level: intermediate 78950ffb88aSMatthew Knepley 79050ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 79158ebbce7SBarry Smith 792e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 79358ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 79458ebbce7SBarry Smith 79550ffb88aSMatthew Knepley @*/ 7967087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 79750ffb88aSMatthew Knepley { 79850ffb88aSMatthew Knepley PetscFunctionBegin; 7990700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8004482741eSBarry Smith PetscValidIntPointer(maxFails,2); 80150ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 8023a40ed3dSBarry Smith PetscFunctionReturn(0); 8039b94acceSBarry Smith } 804a847f771SSatish Balay 8054a2ae208SSatish Balay #undef __FUNCT__ 8062541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 8072541af92SBarry Smith /*@ 8082541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 8092541af92SBarry Smith done by SNES. 8102541af92SBarry Smith 8112541af92SBarry Smith Not Collective 8122541af92SBarry Smith 8132541af92SBarry Smith Input Parameter: 8142541af92SBarry Smith . snes - SNES context 8152541af92SBarry Smith 8162541af92SBarry Smith Output Parameter: 8172541af92SBarry Smith . nfuncs - number of evaluations 8182541af92SBarry Smith 8192541af92SBarry Smith Level: intermediate 8202541af92SBarry Smith 8212541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 82258ebbce7SBarry Smith 823e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 8242541af92SBarry Smith @*/ 8257087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 8262541af92SBarry Smith { 8272541af92SBarry Smith PetscFunctionBegin; 8280700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8292541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 8302541af92SBarry Smith *nfuncs = snes->nfuncs; 8312541af92SBarry Smith PetscFunctionReturn(0); 8322541af92SBarry Smith } 8332541af92SBarry Smith 8342541af92SBarry Smith #undef __FUNCT__ 8353d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 8363d4c4710SBarry Smith /*@ 8373d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 8383d4c4710SBarry Smith linear solvers. 8393d4c4710SBarry Smith 8403d4c4710SBarry Smith Not Collective 8413d4c4710SBarry Smith 8423d4c4710SBarry Smith Input Parameter: 8433d4c4710SBarry Smith . snes - SNES context 8443d4c4710SBarry Smith 8453d4c4710SBarry Smith Output Parameter: 8463d4c4710SBarry Smith . nfails - number of failed solves 8473d4c4710SBarry Smith 8483d4c4710SBarry Smith Notes: 8493d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 8503d4c4710SBarry Smith 8513d4c4710SBarry Smith Level: intermediate 8523d4c4710SBarry Smith 8533d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 85458ebbce7SBarry Smith 855e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 8563d4c4710SBarry Smith @*/ 8577087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 8583d4c4710SBarry Smith { 8593d4c4710SBarry Smith PetscFunctionBegin; 8600700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8613d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 8623d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 8633d4c4710SBarry Smith PetscFunctionReturn(0); 8643d4c4710SBarry Smith } 8653d4c4710SBarry Smith 8663d4c4710SBarry Smith #undef __FUNCT__ 8673d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 8683d4c4710SBarry Smith /*@ 8693d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 8703d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 8713d4c4710SBarry Smith 8723f9fe445SBarry Smith Logically Collective on SNES 8733d4c4710SBarry Smith 8743d4c4710SBarry Smith Input Parameters: 8753d4c4710SBarry Smith + snes - SNES context 8763d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 8773d4c4710SBarry Smith 8783d4c4710SBarry Smith Level: intermediate 8793d4c4710SBarry Smith 880a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 8813d4c4710SBarry Smith 8823d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 8833d4c4710SBarry Smith 88458ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 8853d4c4710SBarry Smith @*/ 8867087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 8873d4c4710SBarry Smith { 8883d4c4710SBarry Smith PetscFunctionBegin; 8890700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 890c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 8913d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 8923d4c4710SBarry Smith PetscFunctionReturn(0); 8933d4c4710SBarry Smith } 8943d4c4710SBarry Smith 8953d4c4710SBarry Smith #undef __FUNCT__ 8963d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 8973d4c4710SBarry Smith /*@ 8983d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 8993d4c4710SBarry Smith are allowed before SNES terminates 9003d4c4710SBarry Smith 9013d4c4710SBarry Smith Not Collective 9023d4c4710SBarry Smith 9033d4c4710SBarry Smith Input Parameter: 9043d4c4710SBarry Smith . snes - SNES context 9053d4c4710SBarry Smith 9063d4c4710SBarry Smith Output Parameter: 9073d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 9083d4c4710SBarry Smith 9093d4c4710SBarry Smith Level: intermediate 9103d4c4710SBarry Smith 9113d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 9123d4c4710SBarry Smith 9133d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 9143d4c4710SBarry Smith 915e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 9163d4c4710SBarry Smith @*/ 9177087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 9183d4c4710SBarry Smith { 9193d4c4710SBarry Smith PetscFunctionBegin; 9200700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9213d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 9223d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 9233d4c4710SBarry Smith PetscFunctionReturn(0); 9243d4c4710SBarry Smith } 9253d4c4710SBarry Smith 9263d4c4710SBarry Smith #undef __FUNCT__ 927b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 928c96a6f78SLois Curfman McInnes /*@ 929b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 930c96a6f78SLois Curfman McInnes used by the nonlinear solver. 931c96a6f78SLois Curfman McInnes 932c7afd0dbSLois Curfman McInnes Not Collective 933c7afd0dbSLois Curfman McInnes 934c96a6f78SLois Curfman McInnes Input Parameter: 935c96a6f78SLois Curfman McInnes . snes - SNES context 936c96a6f78SLois Curfman McInnes 937c96a6f78SLois Curfman McInnes Output Parameter: 938c96a6f78SLois Curfman McInnes . lits - number of linear iterations 939c96a6f78SLois Curfman McInnes 940c96a6f78SLois Curfman McInnes Notes: 941c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 942c96a6f78SLois Curfman McInnes 94336851e7fSLois Curfman McInnes Level: intermediate 94436851e7fSLois Curfman McInnes 945c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 9462b668275SBarry Smith 9478c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 948c96a6f78SLois Curfman McInnes @*/ 9497087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 950c96a6f78SLois Curfman McInnes { 9513a40ed3dSBarry Smith PetscFunctionBegin; 9520700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9534482741eSBarry Smith PetscValidIntPointer(lits,2); 954c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 9553a40ed3dSBarry Smith PetscFunctionReturn(0); 956c96a6f78SLois Curfman McInnes } 957c96a6f78SLois Curfman McInnes 9584a2ae208SSatish Balay #undef __FUNCT__ 95994b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 96052baeb72SSatish Balay /*@ 96194b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 9629b94acceSBarry Smith 96394b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 964c7afd0dbSLois Curfman McInnes 9659b94acceSBarry Smith Input Parameter: 9669b94acceSBarry Smith . snes - the SNES context 9679b94acceSBarry Smith 9689b94acceSBarry Smith Output Parameter: 96994b7f48cSBarry Smith . ksp - the KSP context 9709b94acceSBarry Smith 9719b94acceSBarry Smith Notes: 97294b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 9739b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 9742999313aSBarry Smith PC contexts as well. 9759b94acceSBarry Smith 97636851e7fSLois Curfman McInnes Level: beginner 97736851e7fSLois Curfman McInnes 97894b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 9799b94acceSBarry Smith 9802999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 9819b94acceSBarry Smith @*/ 9827087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 9839b94acceSBarry Smith { 9841cee3971SBarry Smith PetscErrorCode ierr; 9851cee3971SBarry Smith 9863a40ed3dSBarry Smith PetscFunctionBegin; 9870700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9884482741eSBarry Smith PetscValidPointer(ksp,2); 9891cee3971SBarry Smith 9901cee3971SBarry Smith if (!snes->ksp) { 9911cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 9921cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 9931cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 9941cee3971SBarry Smith } 99594b7f48cSBarry Smith *ksp = snes->ksp; 9963a40ed3dSBarry Smith PetscFunctionReturn(0); 9979b94acceSBarry Smith } 99882bf6240SBarry Smith 9994a2ae208SSatish Balay #undef __FUNCT__ 10002999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 10012999313aSBarry Smith /*@ 10022999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 10032999313aSBarry Smith 10042999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 10052999313aSBarry Smith 10062999313aSBarry Smith Input Parameters: 10072999313aSBarry Smith + snes - the SNES context 10082999313aSBarry Smith - ksp - the KSP context 10092999313aSBarry Smith 10102999313aSBarry Smith Notes: 10112999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 10122999313aSBarry Smith so this routine is rarely needed. 10132999313aSBarry Smith 10142999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 10152999313aSBarry Smith decreased by one. 10162999313aSBarry Smith 10172999313aSBarry Smith Level: developer 10182999313aSBarry Smith 10192999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 10202999313aSBarry Smith 10212999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 10222999313aSBarry Smith @*/ 10237087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 10242999313aSBarry Smith { 10252999313aSBarry Smith PetscErrorCode ierr; 10262999313aSBarry Smith 10272999313aSBarry Smith PetscFunctionBegin; 10280700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10290700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 10302999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 10317dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1032906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 10332999313aSBarry Smith snes->ksp = ksp; 10342999313aSBarry Smith PetscFunctionReturn(0); 10352999313aSBarry Smith } 10362999313aSBarry Smith 10377adad957SLisandro Dalcin #if 0 10382999313aSBarry Smith #undef __FUNCT__ 10394a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 10406849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1041e24b481bSBarry Smith { 1042e24b481bSBarry Smith PetscFunctionBegin; 1043e24b481bSBarry Smith PetscFunctionReturn(0); 1044e24b481bSBarry Smith } 10457adad957SLisandro Dalcin #endif 1046e24b481bSBarry Smith 10479b94acceSBarry Smith /* -----------------------------------------------------------*/ 10484a2ae208SSatish Balay #undef __FUNCT__ 10494a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 105052baeb72SSatish Balay /*@ 10519b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 10529b94acceSBarry Smith 1053c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1054c7afd0dbSLois Curfman McInnes 1055c7afd0dbSLois Curfman McInnes Input Parameters: 1056906ed7ccSBarry Smith . comm - MPI communicator 10579b94acceSBarry Smith 10589b94acceSBarry Smith Output Parameter: 10599b94acceSBarry Smith . outsnes - the new SNES context 10609b94acceSBarry Smith 1061c7afd0dbSLois Curfman McInnes Options Database Keys: 1062c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1063c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1064c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1065c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1066c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1067c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1068c1f60f51SBarry Smith 106936851e7fSLois Curfman McInnes Level: beginner 107036851e7fSLois Curfman McInnes 10719b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 10729b94acceSBarry Smith 1073a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1074a8054027SBarry Smith 10759b94acceSBarry Smith @*/ 10767087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 10779b94acceSBarry Smith { 1078dfbe8321SBarry Smith PetscErrorCode ierr; 10799b94acceSBarry Smith SNES snes; 1080fa9f3622SBarry Smith SNESKSPEW *kctx; 108137fcc0dbSBarry Smith 10823a40ed3dSBarry Smith PetscFunctionBegin; 1083ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 10848ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 10858ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 10868ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 10878ba1e511SMatthew Knepley #endif 10888ba1e511SMatthew Knepley 10893194b578SJed Brown ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 10907adad957SLisandro Dalcin 109185385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 10922c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 10939b94acceSBarry Smith snes->max_its = 50; 10949750a799SBarry Smith snes->max_funcs = 10000; 10959b94acceSBarry Smith snes->norm = 0.0; 1096b4874afaSBarry Smith snes->rtol = 1.e-8; 1097b4874afaSBarry Smith snes->ttol = 0.0; 109870441072SBarry Smith snes->abstol = 1.e-50; 10999b94acceSBarry Smith snes->xtol = 1.e-8; 11004b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 11019b94acceSBarry Smith snes->nfuncs = 0; 110250ffb88aSMatthew Knepley snes->numFailures = 0; 110350ffb88aSMatthew Knepley snes->maxFailures = 1; 11047a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1105e35cf81dSBarry Smith snes->lagjacobian = 1; 1106a8054027SBarry Smith snes->lagpreconditioner = 1; 1107639f9d9dSBarry Smith snes->numbermonitors = 0; 11089b94acceSBarry Smith snes->data = 0; 11094dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1110186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 11116f24a144SLois Curfman McInnes snes->nwork = 0; 111258c9b817SLisandro Dalcin snes->work = 0; 111358c9b817SLisandro Dalcin snes->nvwork = 0; 111458c9b817SLisandro Dalcin snes->vwork = 0; 1115758f92a0SBarry Smith snes->conv_hist_len = 0; 1116758f92a0SBarry Smith snes->conv_hist_max = 0; 1117758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1118758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1119758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1120184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 11219b94acceSBarry Smith 1122ea630c6eSPeter Brune /* initialize the line search options */ 1123ea630c6eSPeter Brune snes->ls_type = SNES_LS_BASIC; 1124af60355fSPeter Brune snes->ls_its = 1; 1125ea630c6eSPeter Brune snes->damping = 1.0; 1126ea630c6eSPeter Brune snes->maxstep = 1e8; 1127ea630c6eSPeter Brune snes->steptol = 1e-12; 1128ea630c6eSPeter Brune snes->ls_alpha = 1e-4; 1129ea630c6eSPeter Brune snes->ls_monitor = PETSC_NULL; 1130ea630c6eSPeter Brune 1131ea630c6eSPeter Brune snes->ops->linesearch = PETSC_NULL; 1132ea630c6eSPeter Brune snes->precheck = PETSC_NULL; 1133ea630c6eSPeter Brune snes->ops->precheckstep = PETSC_NULL; 1134ea630c6eSPeter Brune snes->postcheck = PETSC_NULL; 1135ea630c6eSPeter Brune snes->ops->postcheckstep= PETSC_NULL; 1136ea630c6eSPeter Brune 11373d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 11383d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 11393d4c4710SBarry Smith 11409b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 114138f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 11429b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 11439b94acceSBarry Smith kctx->version = 2; 11449b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 11459b94acceSBarry Smith this was too large for some test cases */ 114675567043SBarry Smith kctx->rtol_last = 0.0; 11479b94acceSBarry Smith kctx->rtol_max = .9; 11489b94acceSBarry Smith kctx->gamma = 1.0; 114962d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 115071f87433Sdalcinl kctx->alpha2 = kctx->alpha; 11519b94acceSBarry Smith kctx->threshold = .1; 115275567043SBarry Smith kctx->lresid_last = 0.0; 115375567043SBarry Smith kctx->norm_last = 0.0; 11549b94acceSBarry Smith 11559b94acceSBarry Smith *outsnes = snes; 11563a40ed3dSBarry Smith PetscFunctionReturn(0); 11579b94acceSBarry Smith } 11589b94acceSBarry Smith 11594a2ae208SSatish Balay #undef __FUNCT__ 11604a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 11619b94acceSBarry Smith /*@C 11629b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 11639b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 11649b94acceSBarry Smith equations. 11659b94acceSBarry Smith 11663f9fe445SBarry Smith Logically Collective on SNES 1167fee21e36SBarry Smith 1168c7afd0dbSLois Curfman McInnes Input Parameters: 1169c7afd0dbSLois Curfman McInnes + snes - the SNES context 1170c7afd0dbSLois Curfman McInnes . r - vector to store function value 1171de044059SHong Zhang . func - function evaluation routine 1172c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1173c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 11749b94acceSBarry Smith 1175c7afd0dbSLois Curfman McInnes Calling sequence of func: 11768d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1177c7afd0dbSLois Curfman McInnes 1178313e4042SLois Curfman McInnes . f - function vector 1179c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 11809b94acceSBarry Smith 11819b94acceSBarry Smith Notes: 11829b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 11839b94acceSBarry Smith $ f'(x) x = -f(x), 1184c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 11859b94acceSBarry Smith 118636851e7fSLois Curfman McInnes Level: beginner 118736851e7fSLois Curfman McInnes 11889b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 11899b94acceSBarry Smith 11908b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard() 11919b94acceSBarry Smith @*/ 11927087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 11939b94acceSBarry Smith { 119485385478SLisandro Dalcin PetscErrorCode ierr; 11953a40ed3dSBarry Smith PetscFunctionBegin; 11960700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1197d2a683ecSLisandro Dalcin if (r) { 1198d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1199d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 120085385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 12016bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 120285385478SLisandro Dalcin snes->vec_func = r; 1203d2a683ecSLisandro Dalcin } else if (!snes->vec_func && snes->dm) { 1204d2a683ecSLisandro Dalcin ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 1205d2a683ecSLisandro Dalcin } 1206d2a683ecSLisandro Dalcin if (func) snes->ops->computefunction = func; 1207d2a683ecSLisandro Dalcin if (ctx) snes->funP = ctx; 12083a40ed3dSBarry Smith PetscFunctionReturn(0); 12099b94acceSBarry Smith } 12109b94acceSBarry Smith 1211646217ecSPeter Brune 1212646217ecSPeter Brune #undef __FUNCT__ 1213646217ecSPeter Brune #define __FUNCT__ "SNESSetGS" 1214c79ef259SPeter Brune /*@C 1215c79ef259SPeter Brune SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for 1216c79ef259SPeter Brune use with composed nonlinear solvers. 1217c79ef259SPeter Brune 1218c79ef259SPeter Brune Input Parameters: 1219c79ef259SPeter Brune + snes - the SNES context 1220c79ef259SPeter Brune . gsfunc - function evaluation routine 1221c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 1222c79ef259SPeter Brune smoother evaluation routine (may be PETSC_NULL) 1223c79ef259SPeter Brune 1224c79ef259SPeter Brune Calling sequence of func: 1225c79ef259SPeter Brune $ func (SNES snes,Vec x,Vec b,void *ctx); 1226c79ef259SPeter Brune 1227c79ef259SPeter Brune + X - solution vector 1228c79ef259SPeter Brune . B - RHS vector 1229c79ef259SPeter Brune - ctx - optional user-defined function context 1230c79ef259SPeter Brune 1231c79ef259SPeter Brune Notes: 1232c79ef259SPeter Brune The GS routines are used by the composed nonlinear solver to generate 1233c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1234c79ef259SPeter Brune 1235c79ef259SPeter Brune Level: beginner 1236c79ef259SPeter Brune 1237c79ef259SPeter Brune .keywords: SNES, nonlinear, set, function 1238c79ef259SPeter Brune 1239c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS() 1240c79ef259SPeter Brune @*/ 1241646217ecSPeter Brune PetscErrorCode SNESSetGS(SNES snes, PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void *), void * ctx) { 1242646217ecSPeter Brune PetscFunctionBegin; 1243646217ecSPeter Brune if (gsfunc) snes->ops->computegs = gsfunc; 1244646217ecSPeter Brune if (ctx) snes->gsP = ctx; 1245646217ecSPeter Brune PetscFunctionReturn(0); 1246646217ecSPeter Brune } 1247646217ecSPeter Brune 1248d25893d9SBarry Smith #undef __FUNCT__ 12498b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 12508b0a5094SBarry Smith PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 12518b0a5094SBarry Smith { 12528b0a5094SBarry Smith PetscErrorCode ierr; 12538b0a5094SBarry Smith PetscFunctionBegin; 12548b0a5094SBarry Smith /* A(x)*x - b(x) */ 12558b0a5094SBarry Smith ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,snes->jacP);CHKERRQ(ierr); 12568b0a5094SBarry Smith ierr = (*snes->ops->computepfunction)(snes,x,f,snes->funP);CHKERRQ(ierr); 12578b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 12588b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 12598b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 12608b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 12618b0a5094SBarry Smith PetscFunctionReturn(0); 12628b0a5094SBarry Smith } 12638b0a5094SBarry Smith 12648b0a5094SBarry Smith #undef __FUNCT__ 12658b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 12668b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 12678b0a5094SBarry Smith { 12688b0a5094SBarry Smith PetscFunctionBegin; 12698b0a5094SBarry Smith *flag = snes->matstruct; 12708b0a5094SBarry Smith PetscFunctionReturn(0); 12718b0a5094SBarry Smith } 12728b0a5094SBarry Smith 12738b0a5094SBarry Smith #undef __FUNCT__ 12748b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 12758b0a5094SBarry Smith /*@C 12768b0a5094SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration 12778b0a5094SBarry Smith 12788b0a5094SBarry Smith Logically Collective on SNES 12798b0a5094SBarry Smith 12808b0a5094SBarry Smith Input Parameters: 12818b0a5094SBarry Smith + snes - the SNES context 12828b0a5094SBarry Smith . r - vector to store function value 12838b0a5094SBarry Smith . func - function evaluation routine 12848b0a5094SBarry Smith . jmat - normally the same as mat but you can pass another matrix for which you compute the Jacobian of A(x) x - b(x) (see jmat below) 12858b0a5094SBarry Smith . mat - matrix to store A 12868b0a5094SBarry Smith . mfunc - function to compute matrix value 12878b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 12888b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 12898b0a5094SBarry Smith 12908b0a5094SBarry Smith Calling sequence of func: 12918b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 12928b0a5094SBarry Smith 12938b0a5094SBarry Smith + f - function vector 12948b0a5094SBarry Smith - ctx - optional user-defined function context 12958b0a5094SBarry Smith 12968b0a5094SBarry Smith Calling sequence of mfunc: 12978b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 12988b0a5094SBarry Smith 12998b0a5094SBarry Smith + x - input vector 13008b0a5094SBarry Smith . jmat - Form Jacobian matrix of A(x) x - b(x) if available, not there is really no reason to use it in this way since then you can just use SNESSetJacobian(), 13018b0a5094SBarry Smith normally just pass mat in this location 13028b0a5094SBarry Smith . mat - form A(x) matrix 13038b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 13048b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 13058b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 13068b0a5094SBarry Smith 13078b0a5094SBarry Smith Notes: 13088b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 13098b0a5094SBarry Smith 13108b0a5094SBarry Smith $ Solves the equation A(x) x = b(x) via the defect correction algorithm A(x^{n}) (x^{n+1} - x^{n}) = b(x^{n}) - A(x^{n})x^{n} 13118b0a5094SBarry Smith $ Note that when an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = b(x^{n}) iteration. 13128b0a5094SBarry Smith 13138b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 13148b0a5094SBarry Smith 13158b0a5094SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used. 13168b0a5094SBarry Smith 13178b0a5094SBarry Smith There is some controversity over the definition of a Picard iteration for nonlinear systems but almost everyone agrees that it involves a linear solve and some 13188b0a5094SBarry Smith believe it is the iteration A(x^{n}) x^{n+1} = b(x^{n}) hence we use the name Picard. If anyone has an authoritative reference that defines the Picard iteration 13198b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 13208b0a5094SBarry Smith 13218b0a5094SBarry Smith Level: beginner 13228b0a5094SBarry Smith 13238b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 13248b0a5094SBarry Smith 13258b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard() 13268b0a5094SBarry Smith @*/ 13278b0a5094SBarry Smith PetscErrorCode SNESSetPicard(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),Mat jmat, Mat mat, PetscErrorCode (*mfunc)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 13288b0a5094SBarry Smith { 13298b0a5094SBarry Smith PetscErrorCode ierr; 13308b0a5094SBarry Smith PetscFunctionBegin; 13318b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13328b0a5094SBarry Smith snes->ops->computepfunction = func; 13338b0a5094SBarry Smith snes->ops->computepjacobian = mfunc; 13348b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 13358b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 13368b0a5094SBarry Smith PetscFunctionReturn(0); 13378b0a5094SBarry Smith } 13388b0a5094SBarry Smith 13398b0a5094SBarry Smith #undef __FUNCT__ 1340d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1341d25893d9SBarry Smith /*@C 1342d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1343d25893d9SBarry Smith 1344d25893d9SBarry Smith Logically Collective on SNES 1345d25893d9SBarry Smith 1346d25893d9SBarry Smith Input Parameters: 1347d25893d9SBarry Smith + snes - the SNES context 1348d25893d9SBarry Smith . func - function evaluation routine 1349d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1350d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1351d25893d9SBarry Smith 1352d25893d9SBarry Smith Calling sequence of func: 1353d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1354d25893d9SBarry Smith 1355d25893d9SBarry Smith . f - function vector 1356d25893d9SBarry Smith - ctx - optional user-defined function context 1357d25893d9SBarry Smith 1358d25893d9SBarry Smith Level: intermediate 1359d25893d9SBarry Smith 1360d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1361d25893d9SBarry Smith 1362d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1363d25893d9SBarry Smith @*/ 1364d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1365d25893d9SBarry Smith { 1366d25893d9SBarry Smith PetscFunctionBegin; 1367d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1368d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1369d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1370d25893d9SBarry Smith PetscFunctionReturn(0); 1371d25893d9SBarry Smith } 1372d25893d9SBarry Smith 13733ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 13743ab0aad5SBarry Smith #undef __FUNCT__ 13751096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 13761096aae1SMatthew Knepley /*@C 13771096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 13781096aae1SMatthew Knepley it assumes a zero right hand side. 13791096aae1SMatthew Knepley 13803f9fe445SBarry Smith Logically Collective on SNES 13811096aae1SMatthew Knepley 13821096aae1SMatthew Knepley Input Parameter: 13831096aae1SMatthew Knepley . snes - the SNES context 13841096aae1SMatthew Knepley 13851096aae1SMatthew Knepley Output Parameter: 1386bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 13871096aae1SMatthew Knepley 13881096aae1SMatthew Knepley Level: intermediate 13891096aae1SMatthew Knepley 13901096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 13911096aae1SMatthew Knepley 139285385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 13931096aae1SMatthew Knepley @*/ 13947087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 13951096aae1SMatthew Knepley { 13961096aae1SMatthew Knepley PetscFunctionBegin; 13970700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13981096aae1SMatthew Knepley PetscValidPointer(rhs,2); 139985385478SLisandro Dalcin *rhs = snes->vec_rhs; 14001096aae1SMatthew Knepley PetscFunctionReturn(0); 14011096aae1SMatthew Knepley } 14021096aae1SMatthew Knepley 14031096aae1SMatthew Knepley #undef __FUNCT__ 14044a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 14059b94acceSBarry Smith /*@ 140636851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 14079b94acceSBarry Smith SNESSetFunction(). 14089b94acceSBarry Smith 1409c7afd0dbSLois Curfman McInnes Collective on SNES 1410c7afd0dbSLois Curfman McInnes 14119b94acceSBarry Smith Input Parameters: 1412c7afd0dbSLois Curfman McInnes + snes - the SNES context 1413c7afd0dbSLois Curfman McInnes - x - input vector 14149b94acceSBarry Smith 14159b94acceSBarry Smith Output Parameter: 14163638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 14179b94acceSBarry Smith 14181bffabb2SLois Curfman McInnes Notes: 141936851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 142036851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 142136851e7fSLois Curfman McInnes themselves. 142236851e7fSLois Curfman McInnes 142336851e7fSLois Curfman McInnes Level: developer 142436851e7fSLois Curfman McInnes 14259b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 14269b94acceSBarry Smith 1427a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 14289b94acceSBarry Smith @*/ 14297087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 14309b94acceSBarry Smith { 1431dfbe8321SBarry Smith PetscErrorCode ierr; 14329b94acceSBarry Smith 14333a40ed3dSBarry Smith PetscFunctionBegin; 14340700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14350700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 14360700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1437c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1438c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 1439184914b5SBarry Smith 1440d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 1441e7788613SBarry Smith if (snes->ops->computefunction) { 1442d64ed03dSBarry Smith PetscStackPush("SNES user function"); 144339d508bbSBarry Smith ierr = (*snes->ops->computefunction)(snes,x,y,snes->funP);CHKERRQ(ierr); 1444d64ed03dSBarry Smith PetscStackPop; 144573250ac0SBarry Smith } else if (snes->dm) { 1446644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1447c90fad12SPeter Brune } else if (snes->vec_rhs) { 1448c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1449644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 145085385478SLisandro Dalcin if (snes->vec_rhs) { 145185385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 14523ab0aad5SBarry Smith } 1453ae3c334cSLois Curfman McInnes snes->nfuncs++; 1454d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 14553a40ed3dSBarry Smith PetscFunctionReturn(0); 14569b94acceSBarry Smith } 14579b94acceSBarry Smith 14584a2ae208SSatish Balay #undef __FUNCT__ 1459646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1460c79ef259SPeter Brune /*@ 1461c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1462c79ef259SPeter Brune SNESSetGS(). 1463c79ef259SPeter Brune 1464c79ef259SPeter Brune Collective on SNES 1465c79ef259SPeter Brune 1466c79ef259SPeter Brune Input Parameters: 1467c79ef259SPeter Brune + snes - the SNES context 1468c79ef259SPeter Brune . x - input vector 1469c79ef259SPeter Brune - b - rhs vector 1470c79ef259SPeter Brune 1471c79ef259SPeter Brune Output Parameter: 1472c79ef259SPeter Brune . x - new solution vector 1473c79ef259SPeter Brune 1474c79ef259SPeter Brune Notes: 1475c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1476c79ef259SPeter Brune implementations, so most users would not generally call this routine 1477c79ef259SPeter Brune themselves. 1478c79ef259SPeter Brune 1479c79ef259SPeter Brune Level: developer 1480c79ef259SPeter Brune 1481c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1482c79ef259SPeter Brune 1483c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1484c79ef259SPeter Brune @*/ 1485646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1486646217ecSPeter Brune { 1487646217ecSPeter Brune PetscErrorCode ierr; 1488646217ecSPeter Brune 1489646217ecSPeter Brune PetscFunctionBegin; 1490646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1491646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1492646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1493646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 1494646217ecSPeter Brune if(b) PetscCheckSameComm(snes,1,b,3); 1495646217ecSPeter Brune if (snes->ops->computegs) { 1496646217ecSPeter Brune PetscStackPush("SNES user GS"); 1497646217ecSPeter Brune ierr = (*snes->ops->computegs)(snes,x,b,snes->gsP);CHKERRQ(ierr); 1498646217ecSPeter Brune PetscStackPop; 1499646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 1500646217ecSPeter Brune PetscFunctionReturn(0); 1501646217ecSPeter Brune } 1502646217ecSPeter Brune 1503646217ecSPeter Brune 1504646217ecSPeter Brune #undef __FUNCT__ 15054a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 150662fef451SLois Curfman McInnes /*@ 150762fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 150862fef451SLois Curfman McInnes set with SNESSetJacobian(). 150962fef451SLois Curfman McInnes 1510c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1511c7afd0dbSLois Curfman McInnes 151262fef451SLois Curfman McInnes Input Parameters: 1513c7afd0dbSLois Curfman McInnes + snes - the SNES context 1514c7afd0dbSLois Curfman McInnes - x - input vector 151562fef451SLois Curfman McInnes 151662fef451SLois Curfman McInnes Output Parameters: 1517c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 151862fef451SLois Curfman McInnes . B - optional preconditioning matrix 15192b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1520fee21e36SBarry Smith 1521e35cf81dSBarry Smith Options Database Keys: 1522e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1523693365a8SJed Brown . -snes_lag_jacobian <lag> 1524693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1525693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1526693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 15274c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1528c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 1529c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 1530c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 1531c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 1532c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 15334c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 1534c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 1535c01495d3SJed Brown 1536e35cf81dSBarry Smith 153762fef451SLois Curfman McInnes Notes: 153862fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 153962fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 154062fef451SLois Curfman McInnes 154194b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1542dc5a77f8SLois Curfman McInnes flag parameter. 154362fef451SLois Curfman McInnes 154436851e7fSLois Curfman McInnes Level: developer 154536851e7fSLois Curfman McInnes 154662fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 154762fef451SLois Curfman McInnes 1548e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 154962fef451SLois Curfman McInnes @*/ 15507087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 15519b94acceSBarry Smith { 1552dfbe8321SBarry Smith PetscErrorCode ierr; 1553ace3abfcSBarry Smith PetscBool flag; 15543a40ed3dSBarry Smith 15553a40ed3dSBarry Smith PetscFunctionBegin; 15560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15570700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 15584482741eSBarry Smith PetscValidPointer(flg,5); 1559c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 1560e7788613SBarry Smith if (!snes->ops->computejacobian) PetscFunctionReturn(0); 1561ebd3b9afSBarry Smith 1562ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1563ebd3b9afSBarry Smith 1564fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 1565fe3ffe1eSBarry Smith snes->lagjacobian = -1; 1566fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1567fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 1568e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1569e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1570ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1571ebd3b9afSBarry Smith if (flag) { 1572ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1573ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1574ebd3b9afSBarry Smith } 1575e35cf81dSBarry Smith PetscFunctionReturn(0); 1576e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1577e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1578e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1579ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1580ebd3b9afSBarry Smith if (flag) { 1581ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1582ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1583ebd3b9afSBarry Smith } 1584e35cf81dSBarry Smith PetscFunctionReturn(0); 1585e35cf81dSBarry Smith } 1586e35cf81dSBarry Smith 1587c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 1588e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1589d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 1590e7788613SBarry Smith ierr = (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);CHKERRQ(ierr); 1591d64ed03dSBarry Smith PetscStackPop; 1592d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1593a8054027SBarry Smith 15943b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 15953b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 15963b4f5425SBarry Smith snes->lagpreconditioner = -1; 15973b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 1598a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1599a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 1600a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 1601a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1602a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 1603a8054027SBarry Smith } 1604a8054027SBarry Smith 16056d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 16060700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 16070700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 1608693365a8SJed Brown { 1609693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 1610693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 1611693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 1612693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 1613693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 1614693365a8SJed Brown if (flag || flag_draw || flag_contour) { 1615693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 1616693365a8SJed Brown MatStructure mstruct; 1617693365a8SJed Brown PetscViewer vdraw,vstdout; 16186b3a5b13SJed Brown PetscBool flg; 1619693365a8SJed Brown if (flag_operator) { 1620693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 1621693365a8SJed Brown Bexp = Bexp_mine; 1622693365a8SJed Brown } else { 1623693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 1624693365a8SJed Brown ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 1625693365a8SJed Brown if (flg) Bexp = *B; 1626693365a8SJed Brown else { 1627693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 1628693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 1629693365a8SJed Brown Bexp = Bexp_mine; 1630693365a8SJed Brown } 1631693365a8SJed Brown } 1632693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 1633693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 1634693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 1635693365a8SJed Brown if (flag_draw || flag_contour) { 1636693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 1637693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 1638693365a8SJed Brown } else vdraw = PETSC_NULL; 1639693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 1640693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 1641693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 1642693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 1643693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1644693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 1645693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1646693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 1647693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1648693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 1649693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 1650693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 1651693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 1652693365a8SJed Brown } 1653693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 1654693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 1655693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 1656693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 1657693365a8SJed Brown } 1658693365a8SJed Brown } 16594c30e9fbSJed Brown { 16606719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 16616719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 16624c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 16636719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 16644c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 16654c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 16666719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 16676719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 16686719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 16696719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 16704c30e9fbSJed Brown Mat Bfd; 16714c30e9fbSJed Brown MatStructure mstruct; 16724c30e9fbSJed Brown PetscViewer vdraw,vstdout; 16734c30e9fbSJed Brown ISColoring iscoloring; 16744c30e9fbSJed Brown MatFDColoring matfdcoloring; 16754c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 16764c30e9fbSJed Brown void *funcctx; 16776719d8e4SJed Brown PetscReal norm1,norm2,normmax; 16784c30e9fbSJed Brown 16794c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 16804c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 16814c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 16824c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 16834c30e9fbSJed Brown 16844c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 16854c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 16864c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 16874c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 16884c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 16894c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 16904c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 16914c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 16924c30e9fbSJed Brown 16934c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 16944c30e9fbSJed Brown if (flag_draw || flag_contour) { 16954c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 16964c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 16974c30e9fbSJed Brown } else vdraw = PETSC_NULL; 16984c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 16996719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 17004c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 17014c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 17026719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 17034c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 17044c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 17054c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 17066719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 17074c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 17086719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 17096719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 17104c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 17114c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 17124c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 17134c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 17144c30e9fbSJed Brown } 17154c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 17166719d8e4SJed Brown 17176719d8e4SJed Brown if (flag_threshold) { 17186719d8e4SJed Brown PetscInt bs,rstart,rend,i; 17196719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 17206719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 17216719d8e4SJed Brown for (i=rstart; i<rend; i++) { 17226719d8e4SJed Brown const PetscScalar *ba,*ca; 17236719d8e4SJed Brown const PetscInt *bj,*cj; 17246719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 17256719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 17266719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 17276719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 17286719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 17296719d8e4SJed Brown for (j=0; j<bn; j++) { 17306719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 17316719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 17326719d8e4SJed Brown maxentrycol = bj[j]; 17336719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 17346719d8e4SJed Brown } 17356719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 17366719d8e4SJed Brown maxdiffcol = bj[j]; 17376719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 17386719d8e4SJed Brown } 17396719d8e4SJed Brown if (rdiff > maxrdiff) { 17406719d8e4SJed Brown maxrdiffcol = bj[j]; 17416719d8e4SJed Brown maxrdiff = rdiff; 17426719d8e4SJed Brown } 17436719d8e4SJed Brown } 17446719d8e4SJed Brown if (maxrdiff > 1) { 17456719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"row %D (maxentry=%G at %D, maxdiff=%G at %D, maxrdiff=%G at %D):",i,maxentry,maxentrycol,maxdiff,maxdiffcol,maxrdiff,maxrdiffcol);CHKERRQ(ierr); 17466719d8e4SJed Brown for (j=0; j<bn; j++) { 17476719d8e4SJed Brown PetscReal rdiff; 17486719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 17496719d8e4SJed Brown if (rdiff > 1) { 17506719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 17516719d8e4SJed Brown } 17526719d8e4SJed Brown } 17536719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 17546719d8e4SJed Brown } 17556719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 17566719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 17576719d8e4SJed Brown } 17586719d8e4SJed Brown } 17594c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 17604c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 17614c30e9fbSJed Brown } 17624c30e9fbSJed Brown } 17633a40ed3dSBarry Smith PetscFunctionReturn(0); 17649b94acceSBarry Smith } 17659b94acceSBarry Smith 17664a2ae208SSatish Balay #undef __FUNCT__ 17674a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 17689b94acceSBarry Smith /*@C 17699b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 1770044dda88SLois Curfman McInnes location to store the matrix. 17719b94acceSBarry Smith 17723f9fe445SBarry Smith Logically Collective on SNES and Mat 1773c7afd0dbSLois Curfman McInnes 17749b94acceSBarry Smith Input Parameters: 1775c7afd0dbSLois Curfman McInnes + snes - the SNES context 17769b94acceSBarry Smith . A - Jacobian matrix 17779b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 1778efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 1779c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1780efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 17819b94acceSBarry Smith 17829b94acceSBarry Smith Calling sequence of func: 17838d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 17849b94acceSBarry Smith 1785c7afd0dbSLois Curfman McInnes + x - input vector 17869b94acceSBarry Smith . A - Jacobian matrix 17879b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 1788ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 17892b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 1790c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 17919b94acceSBarry Smith 17929b94acceSBarry Smith Notes: 179394b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 17942cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 1795ac21db08SLois Curfman McInnes 1796ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 17979b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 17989b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 17999b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 18009b94acceSBarry Smith throughout the global iterations. 18019b94acceSBarry Smith 180216913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 180316913363SBarry Smith each matrix. 180416913363SBarry Smith 1805a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 1806a8a26c1eSJed Brown must be a MatFDColoring. 1807a8a26c1eSJed Brown 1808c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 1809c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 1810c3cc8fd1SJed Brown 181136851e7fSLois Curfman McInnes Level: beginner 181236851e7fSLois Curfman McInnes 18139b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 18149b94acceSBarry Smith 18153ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 18169b94acceSBarry Smith @*/ 18177087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 18189b94acceSBarry Smith { 1819dfbe8321SBarry Smith PetscErrorCode ierr; 18203a7fca6bSBarry Smith 18213a40ed3dSBarry Smith PetscFunctionBegin; 18220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 18230700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 18240700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 1825c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 182606975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 1827e7788613SBarry Smith if (func) snes->ops->computejacobian = func; 18283a7fca6bSBarry Smith if (ctx) snes->jacP = ctx; 18293a7fca6bSBarry Smith if (A) { 18307dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 18316bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 18329b94acceSBarry Smith snes->jacobian = A; 18333a7fca6bSBarry Smith } 18343a7fca6bSBarry Smith if (B) { 18357dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 18366bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 18379b94acceSBarry Smith snes->jacobian_pre = B; 18383a7fca6bSBarry Smith } 18393a40ed3dSBarry Smith PetscFunctionReturn(0); 18409b94acceSBarry Smith } 184162fef451SLois Curfman McInnes 18424a2ae208SSatish Balay #undef __FUNCT__ 18434a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 1844c2aafc4cSSatish Balay /*@C 1845b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 1846b4fd4287SBarry Smith provided context for evaluating the Jacobian. 1847b4fd4287SBarry Smith 1848c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 1849c7afd0dbSLois Curfman McInnes 1850b4fd4287SBarry Smith Input Parameter: 1851b4fd4287SBarry Smith . snes - the nonlinear solver context 1852b4fd4287SBarry Smith 1853b4fd4287SBarry Smith Output Parameters: 1854c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 1855b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 185670e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 185770e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 1858fee21e36SBarry Smith 185936851e7fSLois Curfman McInnes Level: advanced 186036851e7fSLois Curfman McInnes 1861b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 1862b4fd4287SBarry Smith @*/ 18637087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 1864b4fd4287SBarry Smith { 18653a40ed3dSBarry Smith PetscFunctionBegin; 18660700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1867b4fd4287SBarry Smith if (A) *A = snes->jacobian; 1868b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 1869e7788613SBarry Smith if (func) *func = snes->ops->computejacobian; 187070e92668SMatthew Knepley if (ctx) *ctx = snes->jacP; 18713a40ed3dSBarry Smith PetscFunctionReturn(0); 1872b4fd4287SBarry Smith } 1873b4fd4287SBarry Smith 18749b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 18759b94acceSBarry Smith 18764a2ae208SSatish Balay #undef __FUNCT__ 18774a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 18789b94acceSBarry Smith /*@ 18799b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 1880272ac6f2SLois Curfman McInnes of a nonlinear solver. 18819b94acceSBarry Smith 1882fee21e36SBarry Smith Collective on SNES 1883fee21e36SBarry Smith 1884c7afd0dbSLois Curfman McInnes Input Parameters: 188570e92668SMatthew Knepley . snes - the SNES context 1886c7afd0dbSLois Curfman McInnes 1887272ac6f2SLois Curfman McInnes Notes: 1888272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 1889272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 1890272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 1891272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 1892272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 1893272ac6f2SLois Curfman McInnes 189436851e7fSLois Curfman McInnes Level: advanced 189536851e7fSLois Curfman McInnes 18969b94acceSBarry Smith .keywords: SNES, nonlinear, setup 18979b94acceSBarry Smith 18989b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 18999b94acceSBarry Smith @*/ 19007087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 19019b94acceSBarry Smith { 1902dfbe8321SBarry Smith PetscErrorCode ierr; 19033a40ed3dSBarry Smith 19043a40ed3dSBarry Smith PetscFunctionBegin; 19050700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 19064dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 19079b94acceSBarry Smith 19087adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 190985385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 191085385478SLisandro Dalcin } 191185385478SLisandro Dalcin 1912c9b9fda1SJed Brown if (!snes->vec_func) { 1913c9b9fda1SJed Brown if (snes->vec_rhs) { 1914c9b9fda1SJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 1915c9b9fda1SJed Brown } else if (snes->vec_sol) { 1916c9b9fda1SJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 1917c9b9fda1SJed Brown } else if (snes->dm) { 1918efd51863SBarry Smith ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 1919efd51863SBarry Smith } 1920c9b9fda1SJed Brown } 192117186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 192258c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 192358c9b817SLisandro Dalcin 192458c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 192558c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 192658c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 192758c9b817SLisandro Dalcin } 192858c9b817SLisandro Dalcin 1929ef8dffc7SBarry Smith if (!snes->ops->computejacobian && snes->dm) { 1930ef8dffc7SBarry Smith Mat J; 1931950540a4SJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr); 1932cab2e9ccSBarry Smith ierr = SNESSetJacobian(snes,J,J,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr); 1933cab2e9ccSBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 19342ef29e96SBarry Smith } else if (!snes->jacobian && snes->ops->computejacobian == MatMFFDComputeJacobian) { 1935a8248277SBarry Smith Mat J; 1936a8248277SBarry Smith ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 1937a8248277SBarry Smith ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 1938a8248277SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 1939a8248277SBarry Smith ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);CHKERRQ(ierr); 1940a8248277SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 1941a8248277SBarry Smith } else if (snes->dm && snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 1942a8248277SBarry Smith Mat J,B; 1943a8248277SBarry Smith ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 1944a8248277SBarry Smith ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 1945a8248277SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 1946950540a4SJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 1947a8248277SBarry Smith ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,snes->funP);CHKERRQ(ierr); 1948a8248277SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 1949a8248277SBarry Smith ierr = MatDestroy(&B);CHKERRQ(ierr); 1950efd51863SBarry Smith } else if (snes->dm && !snes->jacobian_pre){ 1951efd51863SBarry Smith Mat J; 1952950540a4SJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr); 19533cbb28f5SBarry Smith ierr = SNESSetJacobian(snes,J,J,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1954efd51863SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 1955ef8dffc7SBarry Smith } 1956cfaf3a74SBarry 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()"); 1957c9b9fda1SJed Brown if (!snes->vec_func) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a vector when calling SNESSetFunction() or call SNESSetDM()"); 1958efd51863SBarry Smith 1959b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 1960b710008aSBarry Smith 1961d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 1962d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 1963d25893d9SBarry Smith } 1964d25893d9SBarry Smith 1965410397dcSLisandro Dalcin if (snes->ops->setup) { 1966410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 1967410397dcSLisandro Dalcin } 196858c9b817SLisandro Dalcin 19697aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 19703a40ed3dSBarry Smith PetscFunctionReturn(0); 19719b94acceSBarry Smith } 19729b94acceSBarry Smith 19734a2ae208SSatish Balay #undef __FUNCT__ 197437596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 197537596af1SLisandro Dalcin /*@ 197637596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 197737596af1SLisandro Dalcin 197837596af1SLisandro Dalcin Collective on SNES 197937596af1SLisandro Dalcin 198037596af1SLisandro Dalcin Input Parameter: 198137596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 198237596af1SLisandro Dalcin 1983d25893d9SBarry Smith Level: intermediate 1984d25893d9SBarry Smith 1985d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 198637596af1SLisandro Dalcin 198737596af1SLisandro Dalcin .keywords: SNES, destroy 198837596af1SLisandro Dalcin 198937596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 199037596af1SLisandro Dalcin @*/ 199137596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 199237596af1SLisandro Dalcin { 199337596af1SLisandro Dalcin PetscErrorCode ierr; 199437596af1SLisandro Dalcin 199537596af1SLisandro Dalcin PetscFunctionBegin; 199637596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1997d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 1998d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 1999d25893d9SBarry Smith snes->user = PETSC_NULL; 2000d25893d9SBarry Smith } 20018a23116dSBarry Smith if (snes->pc) { 20028a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 20038a23116dSBarry Smith } 20048a23116dSBarry Smith 200537596af1SLisandro Dalcin if (snes->ops->reset) { 200637596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 200737596af1SLisandro Dalcin } 200837596af1SLisandro Dalcin if (snes->ksp) {ierr = KSPReset(snes->ksp);CHKERRQ(ierr);} 20096bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 20106bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 20116bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 20126bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 20136bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 20146bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 201537596af1SLisandro Dalcin if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);} 201637596af1SLisandro Dalcin if (snes->vwork) {ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);} 201737596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 201837596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 201937596af1SLisandro Dalcin PetscFunctionReturn(0); 202037596af1SLisandro Dalcin } 202137596af1SLisandro Dalcin 202237596af1SLisandro Dalcin #undef __FUNCT__ 20234a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 202452baeb72SSatish Balay /*@ 20259b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 20269b94acceSBarry Smith with SNESCreate(). 20279b94acceSBarry Smith 2028c7afd0dbSLois Curfman McInnes Collective on SNES 2029c7afd0dbSLois Curfman McInnes 20309b94acceSBarry Smith Input Parameter: 20319b94acceSBarry Smith . snes - the SNES context 20329b94acceSBarry Smith 203336851e7fSLois Curfman McInnes Level: beginner 203436851e7fSLois Curfman McInnes 20359b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 20369b94acceSBarry Smith 203763a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 20389b94acceSBarry Smith @*/ 20396bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 20409b94acceSBarry Smith { 20416849ba73SBarry Smith PetscErrorCode ierr; 20423a40ed3dSBarry Smith 20433a40ed3dSBarry Smith PetscFunctionBegin; 20446bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 20456bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 20466bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2047d4bb536fSBarry Smith 20486bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 20498a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 20506b8b9a38SLisandro Dalcin 2051be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 20526bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 20536bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 20546d4c513bSLisandro Dalcin 20556bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 20566bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 20576b8b9a38SLisandro Dalcin 20586bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 20596bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 20606bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 20616b8b9a38SLisandro Dalcin } 20626bf464f9SBarry Smith if ((*snes)->conv_malloc) { 20636bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 20646bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 206558c9b817SLisandro Dalcin } 2066ea630c6eSPeter Brune ierr = PetscViewerDestroy(&(*snes)->ls_monitor);CHKERRQ(ierr); 20676bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2068a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 20693a40ed3dSBarry Smith PetscFunctionReturn(0); 20709b94acceSBarry Smith } 20719b94acceSBarry Smith 20729b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 20739b94acceSBarry Smith 20744a2ae208SSatish Balay #undef __FUNCT__ 2075a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2076a8054027SBarry Smith /*@ 2077a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2078a8054027SBarry Smith 20793f9fe445SBarry Smith Logically Collective on SNES 2080a8054027SBarry Smith 2081a8054027SBarry Smith Input Parameters: 2082a8054027SBarry Smith + snes - the SNES context 2083a8054027SBarry 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 20843b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2085a8054027SBarry Smith 2086a8054027SBarry Smith Options Database Keys: 2087a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2088a8054027SBarry Smith 2089a8054027SBarry Smith Notes: 2090a8054027SBarry Smith The default is 1 2091a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2092a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2093a8054027SBarry Smith 2094a8054027SBarry Smith Level: intermediate 2095a8054027SBarry Smith 2096a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2097a8054027SBarry Smith 2098e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2099a8054027SBarry Smith 2100a8054027SBarry Smith @*/ 21017087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2102a8054027SBarry Smith { 2103a8054027SBarry Smith PetscFunctionBegin; 21040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2105e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2106e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2107c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2108a8054027SBarry Smith snes->lagpreconditioner = lag; 2109a8054027SBarry Smith PetscFunctionReturn(0); 2110a8054027SBarry Smith } 2111a8054027SBarry Smith 2112a8054027SBarry Smith #undef __FUNCT__ 2113efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2114efd51863SBarry Smith /*@ 2115efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2116efd51863SBarry Smith 2117efd51863SBarry Smith Logically Collective on SNES 2118efd51863SBarry Smith 2119efd51863SBarry Smith Input Parameters: 2120efd51863SBarry Smith + snes - the SNES context 2121efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2122efd51863SBarry Smith 2123efd51863SBarry Smith Options Database Keys: 2124efd51863SBarry Smith . -snes_grid_sequence <steps> 2125efd51863SBarry Smith 2126efd51863SBarry Smith Level: intermediate 2127efd51863SBarry Smith 2128c0df2a02SJed Brown Notes: 2129c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2130c0df2a02SJed Brown 2131efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2132efd51863SBarry Smith 2133efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2134efd51863SBarry Smith 2135efd51863SBarry Smith @*/ 2136efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2137efd51863SBarry Smith { 2138efd51863SBarry Smith PetscFunctionBegin; 2139efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2140efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2141efd51863SBarry Smith snes->gridsequence = steps; 2142efd51863SBarry Smith PetscFunctionReturn(0); 2143efd51863SBarry Smith } 2144efd51863SBarry Smith 2145efd51863SBarry Smith #undef __FUNCT__ 2146a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2147a8054027SBarry Smith /*@ 2148a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2149a8054027SBarry Smith 21503f9fe445SBarry Smith Not Collective 2151a8054027SBarry Smith 2152a8054027SBarry Smith Input Parameter: 2153a8054027SBarry Smith . snes - the SNES context 2154a8054027SBarry Smith 2155a8054027SBarry Smith Output Parameter: 2156a8054027SBarry 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 21573b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2158a8054027SBarry Smith 2159a8054027SBarry Smith Options Database Keys: 2160a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2161a8054027SBarry Smith 2162a8054027SBarry Smith Notes: 2163a8054027SBarry Smith The default is 1 2164a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2165a8054027SBarry Smith 2166a8054027SBarry Smith Level: intermediate 2167a8054027SBarry Smith 2168a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2169a8054027SBarry Smith 2170a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2171a8054027SBarry Smith 2172a8054027SBarry Smith @*/ 21737087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2174a8054027SBarry Smith { 2175a8054027SBarry Smith PetscFunctionBegin; 21760700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2177a8054027SBarry Smith *lag = snes->lagpreconditioner; 2178a8054027SBarry Smith PetscFunctionReturn(0); 2179a8054027SBarry Smith } 2180a8054027SBarry Smith 2181a8054027SBarry Smith #undef __FUNCT__ 2182e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2183e35cf81dSBarry Smith /*@ 2184e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2185e35cf81dSBarry Smith often the preconditioner is rebuilt. 2186e35cf81dSBarry Smith 21873f9fe445SBarry Smith Logically Collective on SNES 2188e35cf81dSBarry Smith 2189e35cf81dSBarry Smith Input Parameters: 2190e35cf81dSBarry Smith + snes - the SNES context 2191e35cf81dSBarry 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 2192fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2193e35cf81dSBarry Smith 2194e35cf81dSBarry Smith Options Database Keys: 2195e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2196e35cf81dSBarry Smith 2197e35cf81dSBarry Smith Notes: 2198e35cf81dSBarry Smith The default is 1 2199e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2200fe3ffe1eSBarry 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 2201fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2202e35cf81dSBarry Smith 2203e35cf81dSBarry Smith Level: intermediate 2204e35cf81dSBarry Smith 2205e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2206e35cf81dSBarry Smith 2207e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2208e35cf81dSBarry Smith 2209e35cf81dSBarry Smith @*/ 22107087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2211e35cf81dSBarry Smith { 2212e35cf81dSBarry Smith PetscFunctionBegin; 22130700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2214e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2215e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2216c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2217e35cf81dSBarry Smith snes->lagjacobian = lag; 2218e35cf81dSBarry Smith PetscFunctionReturn(0); 2219e35cf81dSBarry Smith } 2220e35cf81dSBarry Smith 2221e35cf81dSBarry Smith #undef __FUNCT__ 2222e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2223e35cf81dSBarry Smith /*@ 2224e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2225e35cf81dSBarry Smith 22263f9fe445SBarry Smith Not Collective 2227e35cf81dSBarry Smith 2228e35cf81dSBarry Smith Input Parameter: 2229e35cf81dSBarry Smith . snes - the SNES context 2230e35cf81dSBarry Smith 2231e35cf81dSBarry Smith Output Parameter: 2232e35cf81dSBarry 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 2233e35cf81dSBarry Smith the Jacobian is built etc. 2234e35cf81dSBarry Smith 2235e35cf81dSBarry Smith Options Database Keys: 2236e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2237e35cf81dSBarry Smith 2238e35cf81dSBarry Smith Notes: 2239e35cf81dSBarry Smith The default is 1 2240e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2241e35cf81dSBarry Smith 2242e35cf81dSBarry Smith Level: intermediate 2243e35cf81dSBarry Smith 2244e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2245e35cf81dSBarry Smith 2246e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2247e35cf81dSBarry Smith 2248e35cf81dSBarry Smith @*/ 22497087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2250e35cf81dSBarry Smith { 2251e35cf81dSBarry Smith PetscFunctionBegin; 22520700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2253e35cf81dSBarry Smith *lag = snes->lagjacobian; 2254e35cf81dSBarry Smith PetscFunctionReturn(0); 2255e35cf81dSBarry Smith } 2256e35cf81dSBarry Smith 2257e35cf81dSBarry Smith #undef __FUNCT__ 22584a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 22599b94acceSBarry Smith /*@ 2260d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 22619b94acceSBarry Smith 22623f9fe445SBarry Smith Logically Collective on SNES 2263c7afd0dbSLois Curfman McInnes 22649b94acceSBarry Smith Input Parameters: 2265c7afd0dbSLois Curfman McInnes + snes - the SNES context 226670441072SBarry Smith . abstol - absolute convergence tolerance 226733174efeSLois Curfman McInnes . rtol - relative convergence tolerance 226833174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 226933174efeSLois Curfman McInnes of the change in the solution between steps 227033174efeSLois Curfman McInnes . maxit - maximum number of iterations 2271c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2272fee21e36SBarry Smith 227333174efeSLois Curfman McInnes Options Database Keys: 227470441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2275c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2276c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2277c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2278c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 22799b94acceSBarry Smith 2280d7a720efSLois Curfman McInnes Notes: 22819b94acceSBarry Smith The default maximum number of iterations is 50. 22829b94acceSBarry Smith The default maximum number of function evaluations is 1000. 22839b94acceSBarry Smith 228436851e7fSLois Curfman McInnes Level: intermediate 228536851e7fSLois Curfman McInnes 228633174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 22879b94acceSBarry Smith 22882492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 22899b94acceSBarry Smith @*/ 22907087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 22919b94acceSBarry Smith { 22923a40ed3dSBarry Smith PetscFunctionBegin; 22930700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2294c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2295c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2296c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2297c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2298c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2299c5eb9154SBarry Smith 2300ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2301ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2302ab54825eSJed Brown snes->abstol = abstol; 2303ab54825eSJed Brown } 2304ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2305ab54825eSJed 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); 2306ab54825eSJed Brown snes->rtol = rtol; 2307ab54825eSJed Brown } 2308ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2309ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2310ab54825eSJed Brown snes->xtol = stol; 2311ab54825eSJed Brown } 2312ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2313ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2314ab54825eSJed Brown snes->max_its = maxit; 2315ab54825eSJed Brown } 2316ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2317ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2318ab54825eSJed Brown snes->max_funcs = maxf; 2319ab54825eSJed Brown } 23203a40ed3dSBarry Smith PetscFunctionReturn(0); 23219b94acceSBarry Smith } 23229b94acceSBarry Smith 23234a2ae208SSatish Balay #undef __FUNCT__ 23244a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 23259b94acceSBarry Smith /*@ 232633174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 232733174efeSLois Curfman McInnes 2328c7afd0dbSLois Curfman McInnes Not Collective 2329c7afd0dbSLois Curfman McInnes 233033174efeSLois Curfman McInnes Input Parameters: 2331c7afd0dbSLois Curfman McInnes + snes - the SNES context 233285385478SLisandro Dalcin . atol - absolute convergence tolerance 233333174efeSLois Curfman McInnes . rtol - relative convergence tolerance 233433174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 233533174efeSLois Curfman McInnes of the change in the solution between steps 233633174efeSLois Curfman McInnes . maxit - maximum number of iterations 2337c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2338fee21e36SBarry Smith 233933174efeSLois Curfman McInnes Notes: 234033174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 234133174efeSLois Curfman McInnes 234236851e7fSLois Curfman McInnes Level: intermediate 234336851e7fSLois Curfman McInnes 234433174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 234533174efeSLois Curfman McInnes 234633174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 234733174efeSLois Curfman McInnes @*/ 23487087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 234933174efeSLois Curfman McInnes { 23503a40ed3dSBarry Smith PetscFunctionBegin; 23510700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 235285385478SLisandro Dalcin if (atol) *atol = snes->abstol; 235333174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 235433174efeSLois Curfman McInnes if (stol) *stol = snes->xtol; 235533174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 235633174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 23573a40ed3dSBarry Smith PetscFunctionReturn(0); 235833174efeSLois Curfman McInnes } 235933174efeSLois Curfman McInnes 23604a2ae208SSatish Balay #undef __FUNCT__ 23614a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 236233174efeSLois Curfman McInnes /*@ 23639b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 23649b94acceSBarry Smith 23653f9fe445SBarry Smith Logically Collective on SNES 2366fee21e36SBarry Smith 2367c7afd0dbSLois Curfman McInnes Input Parameters: 2368c7afd0dbSLois Curfman McInnes + snes - the SNES context 2369c7afd0dbSLois Curfman McInnes - tol - tolerance 2370c7afd0dbSLois Curfman McInnes 23719b94acceSBarry Smith Options Database Key: 2372c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 23739b94acceSBarry Smith 237436851e7fSLois Curfman McInnes Level: intermediate 237536851e7fSLois Curfman McInnes 23769b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 23779b94acceSBarry Smith 23782492ecdbSBarry Smith .seealso: SNESSetTolerances() 23799b94acceSBarry Smith @*/ 23807087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 23819b94acceSBarry Smith { 23823a40ed3dSBarry Smith PetscFunctionBegin; 23830700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2384c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 23859b94acceSBarry Smith snes->deltatol = tol; 23863a40ed3dSBarry Smith PetscFunctionReturn(0); 23879b94acceSBarry Smith } 23889b94acceSBarry Smith 2389df9fa365SBarry Smith /* 2390df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2391df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2392df9fa365SBarry Smith macros instead of functions 2393df9fa365SBarry Smith */ 23944a2ae208SSatish Balay #undef __FUNCT__ 2395a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 23967087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2397ce1608b8SBarry Smith { 2398dfbe8321SBarry Smith PetscErrorCode ierr; 2399ce1608b8SBarry Smith 2400ce1608b8SBarry Smith PetscFunctionBegin; 24010700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2402a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2403ce1608b8SBarry Smith PetscFunctionReturn(0); 2404ce1608b8SBarry Smith } 2405ce1608b8SBarry Smith 24064a2ae208SSatish Balay #undef __FUNCT__ 2407a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 24087087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2409df9fa365SBarry Smith { 2410dfbe8321SBarry Smith PetscErrorCode ierr; 2411df9fa365SBarry Smith 2412df9fa365SBarry Smith PetscFunctionBegin; 2413a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2414df9fa365SBarry Smith PetscFunctionReturn(0); 2415df9fa365SBarry Smith } 2416df9fa365SBarry Smith 24174a2ae208SSatish Balay #undef __FUNCT__ 2418a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 24196bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2420df9fa365SBarry Smith { 2421dfbe8321SBarry Smith PetscErrorCode ierr; 2422df9fa365SBarry Smith 2423df9fa365SBarry Smith PetscFunctionBegin; 2424a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2425df9fa365SBarry Smith PetscFunctionReturn(0); 2426df9fa365SBarry Smith } 2427df9fa365SBarry Smith 24287087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2429b271bb04SBarry Smith #undef __FUNCT__ 2430b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 24317087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2432b271bb04SBarry Smith { 2433b271bb04SBarry Smith PetscDrawLG lg; 2434b271bb04SBarry Smith PetscErrorCode ierr; 2435b271bb04SBarry Smith PetscReal x,y,per; 2436b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2437b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2438b271bb04SBarry Smith PetscDraw draw; 2439b271bb04SBarry Smith PetscFunctionBegin; 2440b271bb04SBarry Smith if (!monctx) { 2441b271bb04SBarry Smith MPI_Comm comm; 2442b271bb04SBarry Smith 2443b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2444b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2445b271bb04SBarry Smith } 2446b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2447b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2448b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2449b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2450b271bb04SBarry Smith x = (PetscReal) n; 2451b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2452b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2453b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2454b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2455b271bb04SBarry Smith } 2456b271bb04SBarry Smith 2457b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2458b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2459b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2460b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2461b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2462b271bb04SBarry Smith x = (PetscReal) n; 2463b271bb04SBarry Smith y = 100.0*per; 2464b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2465b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2466b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2467b271bb04SBarry Smith } 2468b271bb04SBarry Smith 2469b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2470b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2471b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2472b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2473b271bb04SBarry Smith x = (PetscReal) n; 2474b271bb04SBarry Smith y = (prev - rnorm)/prev; 2475b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2476b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2477b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2478b271bb04SBarry Smith } 2479b271bb04SBarry Smith 2480b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2481b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2482b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2483b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2484b271bb04SBarry Smith x = (PetscReal) n; 2485b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2486b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2487b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2488b271bb04SBarry Smith } 2489b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2490b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2491b271bb04SBarry Smith } 2492b271bb04SBarry Smith prev = rnorm; 2493b271bb04SBarry Smith PetscFunctionReturn(0); 2494b271bb04SBarry Smith } 2495b271bb04SBarry Smith 2496b271bb04SBarry Smith #undef __FUNCT__ 2497b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 24987087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2499b271bb04SBarry Smith { 2500b271bb04SBarry Smith PetscErrorCode ierr; 2501b271bb04SBarry Smith 2502b271bb04SBarry Smith PetscFunctionBegin; 2503b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2504b271bb04SBarry Smith PetscFunctionReturn(0); 2505b271bb04SBarry Smith } 2506b271bb04SBarry Smith 2507b271bb04SBarry Smith #undef __FUNCT__ 2508b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 25096bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2510b271bb04SBarry Smith { 2511b271bb04SBarry Smith PetscErrorCode ierr; 2512b271bb04SBarry Smith 2513b271bb04SBarry Smith PetscFunctionBegin; 2514b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2515b271bb04SBarry Smith PetscFunctionReturn(0); 2516b271bb04SBarry Smith } 2517b271bb04SBarry Smith 25187a03ce2fSLisandro Dalcin #undef __FUNCT__ 25197a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 2520228d79bcSJed Brown /*@ 2521228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 2522228d79bcSJed Brown 2523228d79bcSJed Brown Collective on SNES 2524228d79bcSJed Brown 2525228d79bcSJed Brown Input Parameters: 2526228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 2527228d79bcSJed Brown . iter - iteration number 2528228d79bcSJed Brown - rnorm - relative norm of the residual 2529228d79bcSJed Brown 2530228d79bcSJed Brown Notes: 2531228d79bcSJed Brown This routine is called by the SNES implementations. 2532228d79bcSJed Brown It does not typically need to be called by the user. 2533228d79bcSJed Brown 2534228d79bcSJed Brown Level: developer 2535228d79bcSJed Brown 2536228d79bcSJed Brown .seealso: SNESMonitorSet() 2537228d79bcSJed Brown @*/ 25387a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 25397a03ce2fSLisandro Dalcin { 25407a03ce2fSLisandro Dalcin PetscErrorCode ierr; 25417a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 25427a03ce2fSLisandro Dalcin 25437a03ce2fSLisandro Dalcin PetscFunctionBegin; 25447a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 25457a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 25467a03ce2fSLisandro Dalcin } 25477a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 25487a03ce2fSLisandro Dalcin } 25497a03ce2fSLisandro Dalcin 25509b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 25519b94acceSBarry Smith 25524a2ae208SSatish Balay #undef __FUNCT__ 2553a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 25549b94acceSBarry Smith /*@C 2555a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 25569b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 25579b94acceSBarry Smith progress. 25589b94acceSBarry Smith 25593f9fe445SBarry Smith Logically Collective on SNES 2560fee21e36SBarry Smith 2561c7afd0dbSLois Curfman McInnes Input Parameters: 2562c7afd0dbSLois Curfman McInnes + snes - the SNES context 2563c7afd0dbSLois Curfman McInnes . func - monitoring routine 2564b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 2565e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 2566b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 2567b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 25689b94acceSBarry Smith 2569c7afd0dbSLois Curfman McInnes Calling sequence of func: 2570a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2571c7afd0dbSLois Curfman McInnes 2572c7afd0dbSLois Curfman McInnes + snes - the SNES context 2573c7afd0dbSLois Curfman McInnes . its - iteration number 2574c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 257540a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 25769b94acceSBarry Smith 25779665c990SLois Curfman McInnes Options Database Keys: 2578a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 2579a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 2580a6570f20SBarry Smith uses SNESMonitorLGCreate() 2581cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 2582c7afd0dbSLois Curfman McInnes been hardwired into a code by 2583a6570f20SBarry Smith calls to SNESMonitorSet(), but 2584c7afd0dbSLois Curfman McInnes does not cancel those set via 2585c7afd0dbSLois Curfman McInnes the options database. 25869665c990SLois Curfman McInnes 2587639f9d9dSBarry Smith Notes: 25886bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 2589a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 25906bc08f3fSLois Curfman McInnes order in which they were set. 2591639f9d9dSBarry Smith 2592025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 2593025f1a04SBarry Smith 259436851e7fSLois Curfman McInnes Level: intermediate 259536851e7fSLois Curfman McInnes 25969b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 25979b94acceSBarry Smith 2598a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 25999b94acceSBarry Smith @*/ 2600c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 26019b94acceSBarry Smith { 2602b90d0a6eSBarry Smith PetscInt i; 2603649052a6SBarry Smith PetscErrorCode ierr; 2604b90d0a6eSBarry Smith 26053a40ed3dSBarry Smith PetscFunctionBegin; 26060700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 260717186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2608b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 2609649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 2610649052a6SBarry Smith if (monitordestroy) { 2611c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 2612649052a6SBarry Smith } 2613b90d0a6eSBarry Smith PetscFunctionReturn(0); 2614b90d0a6eSBarry Smith } 2615b90d0a6eSBarry Smith } 2616b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 2617b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 2618639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 26193a40ed3dSBarry Smith PetscFunctionReturn(0); 26209b94acceSBarry Smith } 26219b94acceSBarry Smith 26224a2ae208SSatish Balay #undef __FUNCT__ 2623a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 26245cd90555SBarry Smith /*@C 2625a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 26265cd90555SBarry Smith 26273f9fe445SBarry Smith Logically Collective on SNES 2628c7afd0dbSLois Curfman McInnes 26295cd90555SBarry Smith Input Parameters: 26305cd90555SBarry Smith . snes - the SNES context 26315cd90555SBarry Smith 26321a480d89SAdministrator Options Database Key: 2633a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 2634a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 2635c7afd0dbSLois Curfman McInnes set via the options database 26365cd90555SBarry Smith 26375cd90555SBarry Smith Notes: 26385cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 26395cd90555SBarry Smith 264036851e7fSLois Curfman McInnes Level: intermediate 264136851e7fSLois Curfman McInnes 26425cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 26435cd90555SBarry Smith 2644a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 26455cd90555SBarry Smith @*/ 26467087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 26475cd90555SBarry Smith { 2648d952e501SBarry Smith PetscErrorCode ierr; 2649d952e501SBarry Smith PetscInt i; 2650d952e501SBarry Smith 26515cd90555SBarry Smith PetscFunctionBegin; 26520700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2653d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 2654d952e501SBarry Smith if (snes->monitordestroy[i]) { 26553c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 2656d952e501SBarry Smith } 2657d952e501SBarry Smith } 26585cd90555SBarry Smith snes->numbermonitors = 0; 26595cd90555SBarry Smith PetscFunctionReturn(0); 26605cd90555SBarry Smith } 26615cd90555SBarry Smith 26624a2ae208SSatish Balay #undef __FUNCT__ 26634a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 26649b94acceSBarry Smith /*@C 26659b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 26669b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 26679b94acceSBarry Smith 26683f9fe445SBarry Smith Logically Collective on SNES 2669fee21e36SBarry Smith 2670c7afd0dbSLois Curfman McInnes Input Parameters: 2671c7afd0dbSLois Curfman McInnes + snes - the SNES context 2672c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 26737f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 26747f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 26759b94acceSBarry Smith 2676c7afd0dbSLois Curfman McInnes Calling sequence of func: 267706ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 2678c7afd0dbSLois Curfman McInnes 2679c7afd0dbSLois Curfman McInnes + snes - the SNES context 268006ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 2681c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 2682184914b5SBarry Smith . reason - reason for convergence/divergence 2683c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 26844b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 26854b27c08aSLois Curfman McInnes - f - 2-norm of function 26869b94acceSBarry Smith 268736851e7fSLois Curfman McInnes Level: advanced 268836851e7fSLois Curfman McInnes 26899b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 26909b94acceSBarry Smith 269185385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 26929b94acceSBarry Smith @*/ 26937087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 26949b94acceSBarry Smith { 26957f7931b9SBarry Smith PetscErrorCode ierr; 26967f7931b9SBarry Smith 26973a40ed3dSBarry Smith PetscFunctionBegin; 26980700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 269985385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 27007f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 27017f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 27027f7931b9SBarry Smith } 270385385478SLisandro Dalcin snes->ops->converged = func; 27047f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 270585385478SLisandro Dalcin snes->cnvP = cctx; 27063a40ed3dSBarry Smith PetscFunctionReturn(0); 27079b94acceSBarry Smith } 27089b94acceSBarry Smith 27094a2ae208SSatish Balay #undef __FUNCT__ 27104a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 271152baeb72SSatish Balay /*@ 2712184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 2713184914b5SBarry Smith 2714184914b5SBarry Smith Not Collective 2715184914b5SBarry Smith 2716184914b5SBarry Smith Input Parameter: 2717184914b5SBarry Smith . snes - the SNES context 2718184914b5SBarry Smith 2719184914b5SBarry Smith Output Parameter: 27204d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 2721184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 2722184914b5SBarry Smith 2723184914b5SBarry Smith Level: intermediate 2724184914b5SBarry Smith 2725184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 2726184914b5SBarry Smith 2727184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 2728184914b5SBarry Smith 272985385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 2730184914b5SBarry Smith @*/ 27317087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 2732184914b5SBarry Smith { 2733184914b5SBarry Smith PetscFunctionBegin; 27340700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 27354482741eSBarry Smith PetscValidPointer(reason,2); 2736184914b5SBarry Smith *reason = snes->reason; 2737184914b5SBarry Smith PetscFunctionReturn(0); 2738184914b5SBarry Smith } 2739184914b5SBarry Smith 27404a2ae208SSatish Balay #undef __FUNCT__ 27414a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 2742c9005455SLois Curfman McInnes /*@ 2743c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 2744c9005455SLois Curfman McInnes 27453f9fe445SBarry Smith Logically Collective on SNES 2746fee21e36SBarry Smith 2747c7afd0dbSLois Curfman McInnes Input Parameters: 2748c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 27498c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 2750cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 2751758f92a0SBarry Smith . na - size of a and its 275264731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 2753758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 2754c7afd0dbSLois Curfman McInnes 2755308dcc3eSBarry Smith Notes: 2756308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 2757308dcc3eSBarry Smith default array of length 10000 is allocated. 2758308dcc3eSBarry Smith 2759c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 2760c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 2761c9005455SLois Curfman McInnes during the section of code that is being timed. 2762c9005455SLois Curfman McInnes 276336851e7fSLois Curfman McInnes Level: intermediate 276436851e7fSLois Curfman McInnes 2765c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 2766758f92a0SBarry Smith 276708405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 2768758f92a0SBarry Smith 2769c9005455SLois Curfman McInnes @*/ 27707087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 2771c9005455SLois Curfman McInnes { 2772308dcc3eSBarry Smith PetscErrorCode ierr; 2773308dcc3eSBarry Smith 27743a40ed3dSBarry Smith PetscFunctionBegin; 27750700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 27764482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 2777a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 2778308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 2779308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 2780308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 2781308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 2782308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 2783308dcc3eSBarry Smith } 2784c9005455SLois Curfman McInnes snes->conv_hist = a; 2785758f92a0SBarry Smith snes->conv_hist_its = its; 2786758f92a0SBarry Smith snes->conv_hist_max = na; 2787a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 2788758f92a0SBarry Smith snes->conv_hist_reset = reset; 2789758f92a0SBarry Smith PetscFunctionReturn(0); 2790758f92a0SBarry Smith } 2791758f92a0SBarry Smith 2792308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 2793c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 2794c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 2795308dcc3eSBarry Smith EXTERN_C_BEGIN 2796308dcc3eSBarry Smith #undef __FUNCT__ 2797308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 2798308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 2799308dcc3eSBarry Smith { 2800308dcc3eSBarry Smith mxArray *mat; 2801308dcc3eSBarry Smith PetscInt i; 2802308dcc3eSBarry Smith PetscReal *ar; 2803308dcc3eSBarry Smith 2804308dcc3eSBarry Smith PetscFunctionBegin; 2805308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 2806308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 2807308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 2808308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 2809308dcc3eSBarry Smith } 2810308dcc3eSBarry Smith PetscFunctionReturn(mat); 2811308dcc3eSBarry Smith } 2812308dcc3eSBarry Smith EXTERN_C_END 2813308dcc3eSBarry Smith #endif 2814308dcc3eSBarry Smith 2815308dcc3eSBarry Smith 28164a2ae208SSatish Balay #undef __FUNCT__ 28174a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 28180c4c9dddSBarry Smith /*@C 2819758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 2820758f92a0SBarry Smith 28213f9fe445SBarry Smith Not Collective 2822758f92a0SBarry Smith 2823758f92a0SBarry Smith Input Parameter: 2824758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 2825758f92a0SBarry Smith 2826758f92a0SBarry Smith Output Parameters: 2827758f92a0SBarry Smith . a - array to hold history 2828758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 2829758f92a0SBarry Smith negative if not converged) for each solve. 2830758f92a0SBarry Smith - na - size of a and its 2831758f92a0SBarry Smith 2832758f92a0SBarry Smith Notes: 2833758f92a0SBarry Smith The calling sequence for this routine in Fortran is 2834758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 2835758f92a0SBarry Smith 2836758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 2837758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 2838758f92a0SBarry Smith during the section of code that is being timed. 2839758f92a0SBarry Smith 2840758f92a0SBarry Smith Level: intermediate 2841758f92a0SBarry Smith 2842758f92a0SBarry Smith .keywords: SNES, get, convergence, history 2843758f92a0SBarry Smith 2844758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 2845758f92a0SBarry Smith 2846758f92a0SBarry Smith @*/ 28477087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 2848758f92a0SBarry Smith { 2849758f92a0SBarry Smith PetscFunctionBegin; 28500700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2851758f92a0SBarry Smith if (a) *a = snes->conv_hist; 2852758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 2853758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 28543a40ed3dSBarry Smith PetscFunctionReturn(0); 2855c9005455SLois Curfman McInnes } 2856c9005455SLois Curfman McInnes 2857e74ef692SMatthew Knepley #undef __FUNCT__ 2858e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 2859ac226902SBarry Smith /*@C 286076b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 2861eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 28627e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 286376b2cf59SMatthew Knepley 28643f9fe445SBarry Smith Logically Collective on SNES 286576b2cf59SMatthew Knepley 286676b2cf59SMatthew Knepley Input Parameters: 286776b2cf59SMatthew Knepley . snes - The nonlinear solver context 286876b2cf59SMatthew Knepley . func - The function 286976b2cf59SMatthew Knepley 287076b2cf59SMatthew Knepley Calling sequence of func: 2871b5d30489SBarry Smith . func (SNES snes, PetscInt step); 287276b2cf59SMatthew Knepley 287376b2cf59SMatthew Knepley . step - The current step of the iteration 287476b2cf59SMatthew Knepley 2875fe97e370SBarry Smith Level: advanced 2876fe97e370SBarry Smith 2877fe97e370SBarry 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() 2878fe97e370SBarry Smith This is not used by most users. 287976b2cf59SMatthew Knepley 288076b2cf59SMatthew Knepley .keywords: SNES, update 2881b5d30489SBarry Smith 288285385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 288376b2cf59SMatthew Knepley @*/ 28847087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 288576b2cf59SMatthew Knepley { 288676b2cf59SMatthew Knepley PetscFunctionBegin; 28870700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 2888e7788613SBarry Smith snes->ops->update = func; 288976b2cf59SMatthew Knepley PetscFunctionReturn(0); 289076b2cf59SMatthew Knepley } 289176b2cf59SMatthew Knepley 2892e74ef692SMatthew Knepley #undef __FUNCT__ 2893e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 289476b2cf59SMatthew Knepley /*@ 289576b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 289676b2cf59SMatthew Knepley 289776b2cf59SMatthew Knepley Not collective 289876b2cf59SMatthew Knepley 289976b2cf59SMatthew Knepley Input Parameters: 290076b2cf59SMatthew Knepley . snes - The nonlinear solver context 290176b2cf59SMatthew Knepley . step - The current step of the iteration 290276b2cf59SMatthew Knepley 2903205452f4SMatthew Knepley Level: intermediate 2904205452f4SMatthew Knepley 290576b2cf59SMatthew Knepley .keywords: SNES, update 2906a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 290776b2cf59SMatthew Knepley @*/ 29087087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 290976b2cf59SMatthew Knepley { 291076b2cf59SMatthew Knepley PetscFunctionBegin; 291176b2cf59SMatthew Knepley PetscFunctionReturn(0); 291276b2cf59SMatthew Knepley } 291376b2cf59SMatthew Knepley 29144a2ae208SSatish Balay #undef __FUNCT__ 29154a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 29169b94acceSBarry Smith /* 29179b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 29189b94acceSBarry Smith positive parameter delta. 29199b94acceSBarry Smith 29209b94acceSBarry Smith Input Parameters: 2921c7afd0dbSLois Curfman McInnes + snes - the SNES context 29229b94acceSBarry Smith . y - approximate solution of linear system 29239b94acceSBarry Smith . fnorm - 2-norm of current function 2924c7afd0dbSLois Curfman McInnes - delta - trust region size 29259b94acceSBarry Smith 29269b94acceSBarry Smith Output Parameters: 2927c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 29289b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 29299b94acceSBarry Smith region, and exceeds zero otherwise. 2930c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 29319b94acceSBarry Smith 29329b94acceSBarry Smith Note: 29334b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 29349b94acceSBarry Smith is set to be the maximum allowable step size. 29359b94acceSBarry Smith 29369b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 29379b94acceSBarry Smith */ 2938dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 29399b94acceSBarry Smith { 2940064f8208SBarry Smith PetscReal nrm; 2941ea709b57SSatish Balay PetscScalar cnorm; 2942dfbe8321SBarry Smith PetscErrorCode ierr; 29433a40ed3dSBarry Smith 29443a40ed3dSBarry Smith PetscFunctionBegin; 29450700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 29460700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 2947c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 2948184914b5SBarry Smith 2949064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 2950064f8208SBarry Smith if (nrm > *delta) { 2951064f8208SBarry Smith nrm = *delta/nrm; 2952064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 2953064f8208SBarry Smith cnorm = nrm; 29542dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 29559b94acceSBarry Smith *ynorm = *delta; 29569b94acceSBarry Smith } else { 29579b94acceSBarry Smith *gpnorm = 0.0; 2958064f8208SBarry Smith *ynorm = nrm; 29599b94acceSBarry Smith } 29603a40ed3dSBarry Smith PetscFunctionReturn(0); 29619b94acceSBarry Smith } 29629b94acceSBarry Smith 29634a2ae208SSatish Balay #undef __FUNCT__ 29644a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 29656ce558aeSBarry Smith /*@C 2966f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 2967f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 29689b94acceSBarry Smith 2969c7afd0dbSLois Curfman McInnes Collective on SNES 2970c7afd0dbSLois Curfman McInnes 2971b2002411SLois Curfman McInnes Input Parameters: 2972c7afd0dbSLois Curfman McInnes + snes - the SNES context 29733cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 297485385478SLisandro Dalcin - x - the solution vector. 29759b94acceSBarry Smith 2976b2002411SLois Curfman McInnes Notes: 29778ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 29788ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 29798ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 29808ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 29818ddd3da0SLois Curfman McInnes 298236851e7fSLois Curfman McInnes Level: beginner 298336851e7fSLois Curfman McInnes 29849b94acceSBarry Smith .keywords: SNES, nonlinear, solve 29859b94acceSBarry Smith 2986c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 29879b94acceSBarry Smith @*/ 29887087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 29899b94acceSBarry Smith { 2990dfbe8321SBarry Smith PetscErrorCode ierr; 2991ace3abfcSBarry Smith PetscBool flg; 2992eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 2993eabae89aSBarry Smith PetscViewer viewer; 2994efd51863SBarry Smith PetscInt grid; 2995052efed2SBarry Smith 29963a40ed3dSBarry Smith PetscFunctionBegin; 29970700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 29980700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,3); 2999f69a0ea3SMatthew Knepley PetscCheckSameComm(snes,1,x,3); 30000700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 300185385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 300285385478SLisandro Dalcin 3003a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3004efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3005efd51863SBarry Smith 300685385478SLisandro Dalcin /* set solution vector */ 3007efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 30086bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 300985385478SLisandro Dalcin snes->vec_sol = x; 301085385478SLisandro Dalcin /* set afine vector if provided */ 301185385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 30126bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 301385385478SLisandro Dalcin snes->vec_rhs = b; 301485385478SLisandro Dalcin 301570e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 30163f149594SLisandro Dalcin 3017d25893d9SBarry Smith if (!grid && snes->ops->computeinitialguess) { 3018d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3019d25893d9SBarry Smith } 3020d25893d9SBarry Smith 3021abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 302250ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3023d5e45103SBarry Smith 30243f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 30254936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 302685385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 30274936397dSBarry Smith if (snes->domainerror){ 30284936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 30294936397dSBarry Smith snes->domainerror = PETSC_FALSE; 30304936397dSBarry Smith } 303117186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 30323f149594SLisandro Dalcin 30337adad957SLisandro Dalcin ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 3034eabae89aSBarry Smith if (flg && !PetscPreLoadingOn) { 30357adad957SLisandro Dalcin ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 3036eabae89aSBarry Smith ierr = SNESView(snes,viewer);CHKERRQ(ierr); 30376bf464f9SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3038eabae89aSBarry Smith } 3039eabae89aSBarry Smith 304090d69ab7SBarry Smith flg = PETSC_FALSE; 3041acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3042da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 30435968eb51SBarry Smith if (snes->printreason) { 3044a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 30455968eb51SBarry Smith if (snes->reason > 0) { 3046a8248277SBarry Smith ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 30475968eb51SBarry Smith } else { 3048a8248277SBarry Smith ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 30495968eb51SBarry Smith } 3050a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 30515968eb51SBarry Smith } 30525968eb51SBarry Smith 30538501fc72SJed Brown flg = PETSC_FALSE; 30548501fc72SJed Brown ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 30558501fc72SJed Brown if (flg) { 30568501fc72SJed Brown PetscViewer viewer; 30578501fc72SJed Brown ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 30588501fc72SJed Brown ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 30598501fc72SJed Brown ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 30608501fc72SJed Brown ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 30618501fc72SJed Brown ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 30628501fc72SJed Brown } 30638501fc72SJed Brown 3064e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3065efd51863SBarry Smith if (grid < snes->gridsequence) { 3066efd51863SBarry Smith DM fine; 3067efd51863SBarry Smith Vec xnew; 3068efd51863SBarry Smith Mat interp; 3069efd51863SBarry Smith 3070efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3071e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3072efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3073efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3074efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3075efd51863SBarry Smith x = xnew; 3076efd51863SBarry Smith 3077efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3078efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3079efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3080a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3081efd51863SBarry Smith } 3082efd51863SBarry Smith } 30833a40ed3dSBarry Smith PetscFunctionReturn(0); 30849b94acceSBarry Smith } 30859b94acceSBarry Smith 30869b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 30879b94acceSBarry Smith 30884a2ae208SSatish Balay #undef __FUNCT__ 30894a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 309082bf6240SBarry Smith /*@C 30914b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 30929b94acceSBarry Smith 3093fee21e36SBarry Smith Collective on SNES 3094fee21e36SBarry Smith 3095c7afd0dbSLois Curfman McInnes Input Parameters: 3096c7afd0dbSLois Curfman McInnes + snes - the SNES context 3097454a90a3SBarry Smith - type - a known method 3098c7afd0dbSLois Curfman McInnes 3099c7afd0dbSLois Curfman McInnes Options Database Key: 3100454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3101c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3102ae12b187SLois Curfman McInnes 31039b94acceSBarry Smith Notes: 3104e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 31054b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3106c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 31074b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3108c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 31099b94acceSBarry Smith 3110ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3111ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3112ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3113ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3114ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3115ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3116ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3117ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3118ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3119b0a32e0cSBarry Smith appropriate method. 312036851e7fSLois Curfman McInnes 312136851e7fSLois Curfman McInnes Level: intermediate 3122a703fe33SLois Curfman McInnes 3123454a90a3SBarry Smith .keywords: SNES, set, type 3124435da068SBarry Smith 3125435da068SBarry Smith .seealso: SNESType, SNESCreate() 3126435da068SBarry Smith 31279b94acceSBarry Smith @*/ 31287087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 31299b94acceSBarry Smith { 3130dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3131ace3abfcSBarry Smith PetscBool match; 31323a40ed3dSBarry Smith 31333a40ed3dSBarry Smith PetscFunctionBegin; 31340700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31354482741eSBarry Smith PetscValidCharPointer(type,2); 313682bf6240SBarry Smith 31376831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 31380f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 313992ff6ae8SBarry Smith 31404b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3141e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 314275396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 314375396ef9SLisandro Dalcin if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); } 314475396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 314575396ef9SLisandro Dalcin snes->ops->setup = 0; 314675396ef9SLisandro Dalcin snes->ops->solve = 0; 314775396ef9SLisandro Dalcin snes->ops->view = 0; 314875396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 314975396ef9SLisandro Dalcin snes->ops->destroy = 0; 315075396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 315175396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3152454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 315303bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 31549fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 31559fb22e1aSBarry Smith if (PetscAMSPublishAll) { 31569fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 31579fb22e1aSBarry Smith } 31589fb22e1aSBarry Smith #endif 31593a40ed3dSBarry Smith PetscFunctionReturn(0); 31609b94acceSBarry Smith } 31619b94acceSBarry Smith 3162a847f771SSatish Balay 31639b94acceSBarry Smith /* --------------------------------------------------------------------- */ 31644a2ae208SSatish Balay #undef __FUNCT__ 31654a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 316652baeb72SSatish Balay /*@ 31679b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3168f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 31699b94acceSBarry Smith 3170fee21e36SBarry Smith Not Collective 3171fee21e36SBarry Smith 317236851e7fSLois Curfman McInnes Level: advanced 317336851e7fSLois Curfman McInnes 31749b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 31759b94acceSBarry Smith 31769b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 31779b94acceSBarry Smith @*/ 31787087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 31799b94acceSBarry Smith { 3180dfbe8321SBarry Smith PetscErrorCode ierr; 318182bf6240SBarry Smith 31823a40ed3dSBarry Smith PetscFunctionBegin; 31831441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 31844c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 31853a40ed3dSBarry Smith PetscFunctionReturn(0); 31869b94acceSBarry Smith } 31879b94acceSBarry Smith 31884a2ae208SSatish Balay #undef __FUNCT__ 31894a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 31909b94acceSBarry Smith /*@C 31919a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 31929b94acceSBarry Smith 3193c7afd0dbSLois Curfman McInnes Not Collective 3194c7afd0dbSLois Curfman McInnes 31959b94acceSBarry Smith Input Parameter: 31964b0e389bSBarry Smith . snes - nonlinear solver context 31979b94acceSBarry Smith 31989b94acceSBarry Smith Output Parameter: 31993a7fca6bSBarry Smith . type - SNES method (a character string) 32009b94acceSBarry Smith 320136851e7fSLois Curfman McInnes Level: intermediate 320236851e7fSLois Curfman McInnes 3203454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 32049b94acceSBarry Smith @*/ 32057087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 32069b94acceSBarry Smith { 32073a40ed3dSBarry Smith PetscFunctionBegin; 32080700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 32094482741eSBarry Smith PetscValidPointer(type,2); 32107adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 32113a40ed3dSBarry Smith PetscFunctionReturn(0); 32129b94acceSBarry Smith } 32139b94acceSBarry Smith 32144a2ae208SSatish Balay #undef __FUNCT__ 32154a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 321652baeb72SSatish Balay /*@ 32179b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3218c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 32199b94acceSBarry Smith 3220c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3221c7afd0dbSLois Curfman McInnes 32229b94acceSBarry Smith Input Parameter: 32239b94acceSBarry Smith . snes - the SNES context 32249b94acceSBarry Smith 32259b94acceSBarry Smith Output Parameter: 32269b94acceSBarry Smith . x - the solution 32279b94acceSBarry Smith 322870e92668SMatthew Knepley Level: intermediate 322936851e7fSLois Curfman McInnes 32309b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 32319b94acceSBarry Smith 323285385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 32339b94acceSBarry Smith @*/ 32347087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 32359b94acceSBarry Smith { 32363a40ed3dSBarry Smith PetscFunctionBegin; 32370700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 32384482741eSBarry Smith PetscValidPointer(x,2); 323985385478SLisandro Dalcin *x = snes->vec_sol; 324070e92668SMatthew Knepley PetscFunctionReturn(0); 324170e92668SMatthew Knepley } 324270e92668SMatthew Knepley 324370e92668SMatthew Knepley #undef __FUNCT__ 32444a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 324552baeb72SSatish Balay /*@ 32469b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 32479b94acceSBarry Smith stored. 32489b94acceSBarry Smith 3249c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3250c7afd0dbSLois Curfman McInnes 32519b94acceSBarry Smith Input Parameter: 32529b94acceSBarry Smith . snes - the SNES context 32539b94acceSBarry Smith 32549b94acceSBarry Smith Output Parameter: 32559b94acceSBarry Smith . x - the solution update 32569b94acceSBarry Smith 325736851e7fSLois Curfman McInnes Level: advanced 325836851e7fSLois Curfman McInnes 32599b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 32609b94acceSBarry Smith 326185385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 32629b94acceSBarry Smith @*/ 32637087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 32649b94acceSBarry Smith { 32653a40ed3dSBarry Smith PetscFunctionBegin; 32660700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 32674482741eSBarry Smith PetscValidPointer(x,2); 326885385478SLisandro Dalcin *x = snes->vec_sol_update; 32693a40ed3dSBarry Smith PetscFunctionReturn(0); 32709b94acceSBarry Smith } 32719b94acceSBarry Smith 32724a2ae208SSatish Balay #undef __FUNCT__ 32734a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 32749b94acceSBarry Smith /*@C 32753638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 32769b94acceSBarry Smith 3277c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3278c7afd0dbSLois Curfman McInnes 32799b94acceSBarry Smith Input Parameter: 32809b94acceSBarry Smith . snes - the SNES context 32819b94acceSBarry Smith 32829b94acceSBarry Smith Output Parameter: 32837bf4e008SBarry Smith + r - the function (or PETSC_NULL) 328470e92668SMatthew Knepley . func - the function (or PETSC_NULL) 328570e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 32869b94acceSBarry Smith 328736851e7fSLois Curfman McInnes Level: advanced 328836851e7fSLois Curfman McInnes 3289a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 32909b94acceSBarry Smith 32914b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 32929b94acceSBarry Smith @*/ 32937087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 32949b94acceSBarry Smith { 32953a40ed3dSBarry Smith PetscFunctionBegin; 32960700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 329785385478SLisandro Dalcin if (r) *r = snes->vec_func; 3298e7788613SBarry Smith if (func) *func = snes->ops->computefunction; 329970e92668SMatthew Knepley if (ctx) *ctx = snes->funP; 33003a40ed3dSBarry Smith PetscFunctionReturn(0); 33019b94acceSBarry Smith } 33029b94acceSBarry Smith 3303c79ef259SPeter Brune /*@C 3304c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3305c79ef259SPeter Brune 3306c79ef259SPeter Brune Input Parameter: 3307c79ef259SPeter Brune . snes - the SNES context 3308c79ef259SPeter Brune 3309c79ef259SPeter Brune Output Parameter: 3310c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3311c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3312c79ef259SPeter Brune 3313c79ef259SPeter Brune Level: advanced 3314c79ef259SPeter Brune 3315c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3316c79ef259SPeter Brune 3317c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3318c79ef259SPeter Brune @*/ 3319c79ef259SPeter Brune 33204a2ae208SSatish Balay #undef __FUNCT__ 3321646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3322646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3323646217ecSPeter Brune { 3324646217ecSPeter Brune PetscFunctionBegin; 3325646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3326646217ecSPeter Brune if (func) *func = snes->ops->computegs; 3327646217ecSPeter Brune if (ctx) *ctx = snes->funP; 3328646217ecSPeter Brune PetscFunctionReturn(0); 3329646217ecSPeter Brune } 3330646217ecSPeter Brune 33314a2ae208SSatish Balay #undef __FUNCT__ 33324a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 33333c7409f5SSatish Balay /*@C 33343c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3335d850072dSLois Curfman McInnes SNES options in the database. 33363c7409f5SSatish Balay 33373f9fe445SBarry Smith Logically Collective on SNES 3338fee21e36SBarry Smith 3339c7afd0dbSLois Curfman McInnes Input Parameter: 3340c7afd0dbSLois Curfman McInnes + snes - the SNES context 3341c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3342c7afd0dbSLois Curfman McInnes 3343d850072dSLois Curfman McInnes Notes: 3344a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3345c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3346d850072dSLois Curfman McInnes 334736851e7fSLois Curfman McInnes Level: advanced 334836851e7fSLois Curfman McInnes 33493c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3350a86d99e1SLois Curfman McInnes 3351a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 33523c7409f5SSatish Balay @*/ 33537087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 33543c7409f5SSatish Balay { 3355dfbe8321SBarry Smith PetscErrorCode ierr; 33563c7409f5SSatish Balay 33573a40ed3dSBarry Smith PetscFunctionBegin; 33580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3359639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 33601cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 336194b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 33623a40ed3dSBarry Smith PetscFunctionReturn(0); 33633c7409f5SSatish Balay } 33643c7409f5SSatish Balay 33654a2ae208SSatish Balay #undef __FUNCT__ 33664a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 33673c7409f5SSatish Balay /*@C 3368f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3369d850072dSLois Curfman McInnes SNES options in the database. 33703c7409f5SSatish Balay 33713f9fe445SBarry Smith Logically Collective on SNES 3372fee21e36SBarry Smith 3373c7afd0dbSLois Curfman McInnes Input Parameters: 3374c7afd0dbSLois Curfman McInnes + snes - the SNES context 3375c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3376c7afd0dbSLois Curfman McInnes 3377d850072dSLois Curfman McInnes Notes: 3378a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3379c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3380d850072dSLois Curfman McInnes 338136851e7fSLois Curfman McInnes Level: advanced 338236851e7fSLois Curfman McInnes 33833c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3384a86d99e1SLois Curfman McInnes 3385a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 33863c7409f5SSatish Balay @*/ 33877087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 33883c7409f5SSatish Balay { 3389dfbe8321SBarry Smith PetscErrorCode ierr; 33903c7409f5SSatish Balay 33913a40ed3dSBarry Smith PetscFunctionBegin; 33920700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3393639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 33941cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 339594b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 33963a40ed3dSBarry Smith PetscFunctionReturn(0); 33973c7409f5SSatish Balay } 33983c7409f5SSatish Balay 33994a2ae208SSatish Balay #undef __FUNCT__ 34004a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 34019ab63eb5SSatish Balay /*@C 34023c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 34033c7409f5SSatish Balay SNES options in the database. 34043c7409f5SSatish Balay 3405c7afd0dbSLois Curfman McInnes Not Collective 3406c7afd0dbSLois Curfman McInnes 34073c7409f5SSatish Balay Input Parameter: 34083c7409f5SSatish Balay . snes - the SNES context 34093c7409f5SSatish Balay 34103c7409f5SSatish Balay Output Parameter: 34113c7409f5SSatish Balay . prefix - pointer to the prefix string used 34123c7409f5SSatish Balay 34134ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 34149ab63eb5SSatish Balay sufficient length to hold the prefix. 34159ab63eb5SSatish Balay 341636851e7fSLois Curfman McInnes Level: advanced 341736851e7fSLois Curfman McInnes 34183c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 3419a86d99e1SLois Curfman McInnes 3420a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 34213c7409f5SSatish Balay @*/ 34227087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 34233c7409f5SSatish Balay { 3424dfbe8321SBarry Smith PetscErrorCode ierr; 34253c7409f5SSatish Balay 34263a40ed3dSBarry Smith PetscFunctionBegin; 34270700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3428639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 34293a40ed3dSBarry Smith PetscFunctionReturn(0); 34303c7409f5SSatish Balay } 34313c7409f5SSatish Balay 3432b2002411SLois Curfman McInnes 34334a2ae208SSatish Balay #undef __FUNCT__ 34344a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 34353cea93caSBarry Smith /*@C 34363cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 34373cea93caSBarry Smith 34387f6c08e0SMatthew Knepley Level: advanced 34393cea93caSBarry Smith @*/ 34407087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3441b2002411SLois Curfman McInnes { 3442e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3443dfbe8321SBarry Smith PetscErrorCode ierr; 3444b2002411SLois Curfman McInnes 3445b2002411SLois Curfman McInnes PetscFunctionBegin; 3446b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3447c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3448b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3449b2002411SLois Curfman McInnes } 3450da9b6338SBarry Smith 3451da9b6338SBarry Smith #undef __FUNCT__ 3452da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 34537087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3454da9b6338SBarry Smith { 3455dfbe8321SBarry Smith PetscErrorCode ierr; 345677431f27SBarry Smith PetscInt N,i,j; 3457da9b6338SBarry Smith Vec u,uh,fh; 3458da9b6338SBarry Smith PetscScalar value; 3459da9b6338SBarry Smith PetscReal norm; 3460da9b6338SBarry Smith 3461da9b6338SBarry Smith PetscFunctionBegin; 3462da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3463da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3464da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3465da9b6338SBarry Smith 3466da9b6338SBarry Smith /* currently only works for sequential */ 3467da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3468da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3469da9b6338SBarry Smith for (i=0; i<N; i++) { 3470da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 347177431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3472da9b6338SBarry Smith for (j=-10; j<11; j++) { 3473ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3474da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 34753ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3476da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 347777431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3478da9b6338SBarry Smith value = -value; 3479da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3480da9b6338SBarry Smith } 3481da9b6338SBarry Smith } 34826bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 34836bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 3484da9b6338SBarry Smith PetscFunctionReturn(0); 3485da9b6338SBarry Smith } 348671f87433Sdalcinl 348771f87433Sdalcinl #undef __FUNCT__ 3488fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 348971f87433Sdalcinl /*@ 3490fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 349171f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 349271f87433Sdalcinl Newton method. 349371f87433Sdalcinl 34943f9fe445SBarry Smith Logically Collective on SNES 349571f87433Sdalcinl 349671f87433Sdalcinl Input Parameters: 349771f87433Sdalcinl + snes - SNES context 349871f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 349971f87433Sdalcinl 350064ba62caSBarry Smith Options Database: 350164ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 350264ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 350364ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 350464ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 350564ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 350664ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 350764ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 350864ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 350964ba62caSBarry Smith 351071f87433Sdalcinl Notes: 351171f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 351271f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 351371f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 351471f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 351571f87433Sdalcinl solver. 351671f87433Sdalcinl 351771f87433Sdalcinl Level: advanced 351871f87433Sdalcinl 351971f87433Sdalcinl Reference: 352071f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 352171f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 352271f87433Sdalcinl 352371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 352471f87433Sdalcinl 3525fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 352671f87433Sdalcinl @*/ 35277087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 352871f87433Sdalcinl { 352971f87433Sdalcinl PetscFunctionBegin; 35300700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3531acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 353271f87433Sdalcinl snes->ksp_ewconv = flag; 353371f87433Sdalcinl PetscFunctionReturn(0); 353471f87433Sdalcinl } 353571f87433Sdalcinl 353671f87433Sdalcinl #undef __FUNCT__ 3537fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 353871f87433Sdalcinl /*@ 3539fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 354071f87433Sdalcinl for computing relative tolerance for linear solvers within an 354171f87433Sdalcinl inexact Newton method. 354271f87433Sdalcinl 354371f87433Sdalcinl Not Collective 354471f87433Sdalcinl 354571f87433Sdalcinl Input Parameter: 354671f87433Sdalcinl . snes - SNES context 354771f87433Sdalcinl 354871f87433Sdalcinl Output Parameter: 354971f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 355071f87433Sdalcinl 355171f87433Sdalcinl Notes: 355271f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 355371f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 355471f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 355571f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 355671f87433Sdalcinl solver. 355771f87433Sdalcinl 355871f87433Sdalcinl Level: advanced 355971f87433Sdalcinl 356071f87433Sdalcinl Reference: 356171f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 356271f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 356371f87433Sdalcinl 356471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 356571f87433Sdalcinl 3566fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 356771f87433Sdalcinl @*/ 35687087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 356971f87433Sdalcinl { 357071f87433Sdalcinl PetscFunctionBegin; 35710700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 357271f87433Sdalcinl PetscValidPointer(flag,2); 357371f87433Sdalcinl *flag = snes->ksp_ewconv; 357471f87433Sdalcinl PetscFunctionReturn(0); 357571f87433Sdalcinl } 357671f87433Sdalcinl 357771f87433Sdalcinl #undef __FUNCT__ 3578fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 357971f87433Sdalcinl /*@ 3580fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 358171f87433Sdalcinl convergence criteria for the linear solvers within an inexact 358271f87433Sdalcinl Newton method. 358371f87433Sdalcinl 35843f9fe445SBarry Smith Logically Collective on SNES 358571f87433Sdalcinl 358671f87433Sdalcinl Input Parameters: 358771f87433Sdalcinl + snes - SNES context 358871f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 358971f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 359071f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 359171f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 359271f87433Sdalcinl (0 <= gamma2 <= 1) 359371f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 359471f87433Sdalcinl . alpha2 - power for safeguard 359571f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 359671f87433Sdalcinl 359771f87433Sdalcinl Note: 359871f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 359971f87433Sdalcinl 360071f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 360171f87433Sdalcinl 360271f87433Sdalcinl Level: advanced 360371f87433Sdalcinl 360471f87433Sdalcinl Reference: 360571f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 360671f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 360771f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 360871f87433Sdalcinl 360971f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 361071f87433Sdalcinl 3611fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 361271f87433Sdalcinl @*/ 36137087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 361471f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 361571f87433Sdalcinl { 3616fa9f3622SBarry Smith SNESKSPEW *kctx; 361771f87433Sdalcinl PetscFunctionBegin; 36180700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3619fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3620e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 3621c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 3622c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 3623c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 3624c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 3625c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 3626c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 3627c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 362871f87433Sdalcinl 362971f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 363071f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 363171f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 363271f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 363371f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 363471f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 363571f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 363671f87433Sdalcinl 363771f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 3638e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 363971f87433Sdalcinl } 364071f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 3641e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 364271f87433Sdalcinl } 364371f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 3644e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 364571f87433Sdalcinl } 364671f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 3647e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 364871f87433Sdalcinl } 364971f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 3650e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 365171f87433Sdalcinl } 365271f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 3653e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 365471f87433Sdalcinl } 365571f87433Sdalcinl PetscFunctionReturn(0); 365671f87433Sdalcinl } 365771f87433Sdalcinl 365871f87433Sdalcinl #undef __FUNCT__ 3659fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 366071f87433Sdalcinl /*@ 3661fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 366271f87433Sdalcinl convergence criteria for the linear solvers within an inexact 366371f87433Sdalcinl Newton method. 366471f87433Sdalcinl 366571f87433Sdalcinl Not Collective 366671f87433Sdalcinl 366771f87433Sdalcinl Input Parameters: 366871f87433Sdalcinl snes - SNES context 366971f87433Sdalcinl 367071f87433Sdalcinl Output Parameters: 367171f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 367271f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 367371f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 367471f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 367571f87433Sdalcinl (0 <= gamma2 <= 1) 367671f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 367771f87433Sdalcinl . alpha2 - power for safeguard 367871f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 367971f87433Sdalcinl 368071f87433Sdalcinl Level: advanced 368171f87433Sdalcinl 368271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 368371f87433Sdalcinl 3684fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 368571f87433Sdalcinl @*/ 36867087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 368771f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 368871f87433Sdalcinl { 3689fa9f3622SBarry Smith SNESKSPEW *kctx; 369071f87433Sdalcinl PetscFunctionBegin; 36910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3692fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3693e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 369471f87433Sdalcinl if(version) *version = kctx->version; 369571f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 369671f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 369771f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 369871f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 369971f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 370071f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 370171f87433Sdalcinl PetscFunctionReturn(0); 370271f87433Sdalcinl } 370371f87433Sdalcinl 370471f87433Sdalcinl #undef __FUNCT__ 3705fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 3706fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 370771f87433Sdalcinl { 370871f87433Sdalcinl PetscErrorCode ierr; 3709fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 371071f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 371171f87433Sdalcinl 371271f87433Sdalcinl PetscFunctionBegin; 3713e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 371471f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 371571f87433Sdalcinl rtol = kctx->rtol_0; 371671f87433Sdalcinl } else { 371771f87433Sdalcinl if (kctx->version == 1) { 371871f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 371971f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 372071f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 372171f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 372271f87433Sdalcinl } else if (kctx->version == 2) { 372371f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 372471f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 372571f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 372671f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 372771f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 372871f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 372971f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 373071f87433Sdalcinl stol = PetscMax(rtol,stol); 373171f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 373271f87433Sdalcinl /* safeguard: avoid oversolving */ 373371f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 373471f87433Sdalcinl stol = PetscMax(rtol,stol); 373571f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 3736e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 373771f87433Sdalcinl } 373871f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 373971f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 374071f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 374171f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 374271f87433Sdalcinl PetscFunctionReturn(0); 374371f87433Sdalcinl } 374471f87433Sdalcinl 374571f87433Sdalcinl #undef __FUNCT__ 3746fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 3747fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 374871f87433Sdalcinl { 374971f87433Sdalcinl PetscErrorCode ierr; 3750fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 375171f87433Sdalcinl PCSide pcside; 375271f87433Sdalcinl Vec lres; 375371f87433Sdalcinl 375471f87433Sdalcinl PetscFunctionBegin; 3755e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 375671f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 375771f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 375871f87433Sdalcinl if (kctx->version == 1) { 3759b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 376071f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 376171f87433Sdalcinl /* KSP residual is true linear residual */ 376271f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 376371f87433Sdalcinl } else { 376471f87433Sdalcinl /* KSP residual is preconditioned residual */ 376571f87433Sdalcinl /* compute true linear residual norm */ 376671f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 376771f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 376871f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 376971f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 37706bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 377171f87433Sdalcinl } 377271f87433Sdalcinl } 377371f87433Sdalcinl PetscFunctionReturn(0); 377471f87433Sdalcinl } 377571f87433Sdalcinl 377671f87433Sdalcinl #undef __FUNCT__ 377771f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 377871f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 377971f87433Sdalcinl { 378071f87433Sdalcinl PetscErrorCode ierr; 378171f87433Sdalcinl 378271f87433Sdalcinl PetscFunctionBegin; 3783fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 378471f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 3785fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 378671f87433Sdalcinl PetscFunctionReturn(0); 378771f87433Sdalcinl } 37886c699258SBarry Smith 37896c699258SBarry Smith #undef __FUNCT__ 37906c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 37916c699258SBarry Smith /*@ 37926c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 37936c699258SBarry Smith 37943f9fe445SBarry Smith Logically Collective on SNES 37956c699258SBarry Smith 37966c699258SBarry Smith Input Parameters: 37976c699258SBarry Smith + snes - the preconditioner context 37986c699258SBarry Smith - dm - the dm 37996c699258SBarry Smith 38006c699258SBarry Smith Level: intermediate 38016c699258SBarry Smith 38026c699258SBarry Smith 38036c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 38046c699258SBarry Smith @*/ 38057087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 38066c699258SBarry Smith { 38076c699258SBarry Smith PetscErrorCode ierr; 3808345fed2cSBarry Smith KSP ksp; 38096c699258SBarry Smith 38106c699258SBarry Smith PetscFunctionBegin; 38110700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3812d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 38136bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 38146c699258SBarry Smith snes->dm = dm; 3815345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 3816345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 3817f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 38182c155ee1SBarry Smith if (snes->pc) { 38192c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 38202c155ee1SBarry Smith } 38216c699258SBarry Smith PetscFunctionReturn(0); 38226c699258SBarry Smith } 38236c699258SBarry Smith 38246c699258SBarry Smith #undef __FUNCT__ 38256c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 38266c699258SBarry Smith /*@ 38276c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 38286c699258SBarry Smith 38293f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 38306c699258SBarry Smith 38316c699258SBarry Smith Input Parameter: 38326c699258SBarry Smith . snes - the preconditioner context 38336c699258SBarry Smith 38346c699258SBarry Smith Output Parameter: 38356c699258SBarry Smith . dm - the dm 38366c699258SBarry Smith 38376c699258SBarry Smith Level: intermediate 38386c699258SBarry Smith 38396c699258SBarry Smith 38406c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 38416c699258SBarry Smith @*/ 38427087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 38436c699258SBarry Smith { 38446c699258SBarry Smith PetscFunctionBegin; 38450700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 38466c699258SBarry Smith *dm = snes->dm; 38476c699258SBarry Smith PetscFunctionReturn(0); 38486c699258SBarry Smith } 38490807856dSBarry Smith 385031823bd8SMatthew G Knepley #undef __FUNCT__ 385131823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 385231823bd8SMatthew G Knepley /*@ 3853fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 385431823bd8SMatthew G Knepley 385531823bd8SMatthew G Knepley Collective on SNES 385631823bd8SMatthew G Knepley 385731823bd8SMatthew G Knepley Input Parameters: 385831823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 385931823bd8SMatthew G Knepley - pc - the preconditioner object 386031823bd8SMatthew G Knepley 386131823bd8SMatthew G Knepley Notes: 386231823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 386331823bd8SMatthew G Knepley to configure it using the API). 386431823bd8SMatthew G Knepley 386531823bd8SMatthew G Knepley Level: developer 386631823bd8SMatthew G Knepley 386731823bd8SMatthew G Knepley .keywords: SNES, set, precondition 386831823bd8SMatthew G Knepley .seealso: SNESGetPC() 386931823bd8SMatthew G Knepley @*/ 387031823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 387131823bd8SMatthew G Knepley { 387231823bd8SMatthew G Knepley PetscErrorCode ierr; 387331823bd8SMatthew G Knepley 387431823bd8SMatthew G Knepley PetscFunctionBegin; 387531823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 387631823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 387731823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 387831823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 3879bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 388031823bd8SMatthew G Knepley snes->pc = pc; 388131823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 388231823bd8SMatthew G Knepley PetscFunctionReturn(0); 388331823bd8SMatthew G Knepley } 388431823bd8SMatthew G Knepley 388531823bd8SMatthew G Knepley #undef __FUNCT__ 388631823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 388731823bd8SMatthew G Knepley /*@ 3888fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 388931823bd8SMatthew G Knepley 389031823bd8SMatthew G Knepley Not Collective 389131823bd8SMatthew G Knepley 389231823bd8SMatthew G Knepley Input Parameter: 389331823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 389431823bd8SMatthew G Knepley 389531823bd8SMatthew G Knepley Output Parameter: 389631823bd8SMatthew G Knepley . pc - preconditioner context 389731823bd8SMatthew G Knepley 389831823bd8SMatthew G Knepley Level: developer 389931823bd8SMatthew G Knepley 390031823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 390131823bd8SMatthew G Knepley .seealso: SNESSetPC() 390231823bd8SMatthew G Knepley @*/ 390331823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 390431823bd8SMatthew G Knepley { 390531823bd8SMatthew G Knepley PetscErrorCode ierr; 390631823bd8SMatthew G Knepley 390731823bd8SMatthew G Knepley PetscFunctionBegin; 390831823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 390931823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 391031823bd8SMatthew G Knepley if (!snes->pc) { 391131823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr); 39124a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr); 391331823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 391431823bd8SMatthew G Knepley } 391531823bd8SMatthew G Knepley *pc = snes->pc; 391631823bd8SMatthew G Knepley PetscFunctionReturn(0); 391731823bd8SMatthew G Knepley } 391831823bd8SMatthew G Knepley 391969b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3920c6db04a5SJed Brown #include <mex.h> 392169b4f73cSBarry Smith 39228f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 39238f6e6473SBarry Smith 39240807856dSBarry Smith #undef __FUNCT__ 39250807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 39260807856dSBarry Smith /* 39270807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 39280807856dSBarry Smith SNESSetFunctionMatlab(). 39290807856dSBarry Smith 39300807856dSBarry Smith Collective on SNES 39310807856dSBarry Smith 39320807856dSBarry Smith Input Parameters: 39330807856dSBarry Smith + snes - the SNES context 39340807856dSBarry Smith - x - input vector 39350807856dSBarry Smith 39360807856dSBarry Smith Output Parameter: 39370807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 39380807856dSBarry Smith 39390807856dSBarry Smith Notes: 39400807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 39410807856dSBarry Smith implementations, so most users would not generally call this routine 39420807856dSBarry Smith themselves. 39430807856dSBarry Smith 39440807856dSBarry Smith Level: developer 39450807856dSBarry Smith 39460807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 39470807856dSBarry Smith 39480807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 394961b2408cSBarry Smith */ 39507087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 39510807856dSBarry Smith { 3952e650e774SBarry Smith PetscErrorCode ierr; 39538f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 39548f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 39558f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 395691621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 3957e650e774SBarry Smith 39580807856dSBarry Smith PetscFunctionBegin; 39590807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 39600807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 39610807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 39620807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 39630807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 39640807856dSBarry Smith 39650807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 3966e650e774SBarry Smith 396791621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3968e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3969e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 397091621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 397191621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 397291621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 39738f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 39748f6e6473SBarry Smith prhs[4] = sctx->ctx; 3975b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 3976e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3977e650e774SBarry Smith mxDestroyArray(prhs[0]); 3978e650e774SBarry Smith mxDestroyArray(prhs[1]); 3979e650e774SBarry Smith mxDestroyArray(prhs[2]); 39808f6e6473SBarry Smith mxDestroyArray(prhs[3]); 3981e650e774SBarry Smith mxDestroyArray(plhs[0]); 39820807856dSBarry Smith PetscFunctionReturn(0); 39830807856dSBarry Smith } 39840807856dSBarry Smith 39850807856dSBarry Smith 39860807856dSBarry Smith #undef __FUNCT__ 39870807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 398861b2408cSBarry Smith /* 39890807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 39900807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 3991e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 39920807856dSBarry Smith 39930807856dSBarry Smith Logically Collective on SNES 39940807856dSBarry Smith 39950807856dSBarry Smith Input Parameters: 39960807856dSBarry Smith + snes - the SNES context 39970807856dSBarry Smith . r - vector to store function value 39980807856dSBarry Smith - func - function evaluation routine 39990807856dSBarry Smith 40000807856dSBarry Smith Calling sequence of func: 400161b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 40020807856dSBarry Smith 40030807856dSBarry Smith 40040807856dSBarry Smith Notes: 40050807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 40060807856dSBarry Smith $ f'(x) x = -f(x), 40070807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 40080807856dSBarry Smith 40090807856dSBarry Smith Level: beginner 40100807856dSBarry Smith 40110807856dSBarry Smith .keywords: SNES, nonlinear, set, function 40120807856dSBarry Smith 40130807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 401461b2408cSBarry Smith */ 40157087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 40160807856dSBarry Smith { 40170807856dSBarry Smith PetscErrorCode ierr; 40188f6e6473SBarry Smith SNESMatlabContext *sctx; 40190807856dSBarry Smith 40200807856dSBarry Smith PetscFunctionBegin; 40218f6e6473SBarry Smith /* currently sctx is memory bleed */ 40228f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 40238f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 40248f6e6473SBarry Smith /* 40258f6e6473SBarry Smith This should work, but it doesn't 40268f6e6473SBarry Smith sctx->ctx = ctx; 40278f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 40288f6e6473SBarry Smith */ 40298f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 40308f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 40310807856dSBarry Smith PetscFunctionReturn(0); 40320807856dSBarry Smith } 403369b4f73cSBarry Smith 403461b2408cSBarry Smith #undef __FUNCT__ 403561b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 403661b2408cSBarry Smith /* 403761b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 403861b2408cSBarry Smith SNESSetJacobianMatlab(). 403961b2408cSBarry Smith 404061b2408cSBarry Smith Collective on SNES 404161b2408cSBarry Smith 404261b2408cSBarry Smith Input Parameters: 404361b2408cSBarry Smith + snes - the SNES context 404461b2408cSBarry Smith . x - input vector 404561b2408cSBarry Smith . A, B - the matrices 404661b2408cSBarry Smith - ctx - user context 404761b2408cSBarry Smith 404861b2408cSBarry Smith Output Parameter: 404961b2408cSBarry Smith . flag - structure of the matrix 405061b2408cSBarry Smith 405161b2408cSBarry Smith Level: developer 405261b2408cSBarry Smith 405361b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 405461b2408cSBarry Smith 405561b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 405661b2408cSBarry Smith @*/ 40577087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 405861b2408cSBarry Smith { 405961b2408cSBarry Smith PetscErrorCode ierr; 406061b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 406161b2408cSBarry Smith int nlhs = 2,nrhs = 6; 406261b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 406361b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 406461b2408cSBarry Smith 406561b2408cSBarry Smith PetscFunctionBegin; 406661b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 406761b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 406861b2408cSBarry Smith 406961b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 407061b2408cSBarry Smith 407161b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 407261b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 407361b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 407461b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 407561b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 407661b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 407761b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 407861b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 407961b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 408061b2408cSBarry Smith prhs[5] = sctx->ctx; 4081b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 408261b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 408361b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 408461b2408cSBarry Smith mxDestroyArray(prhs[0]); 408561b2408cSBarry Smith mxDestroyArray(prhs[1]); 408661b2408cSBarry Smith mxDestroyArray(prhs[2]); 408761b2408cSBarry Smith mxDestroyArray(prhs[3]); 408861b2408cSBarry Smith mxDestroyArray(prhs[4]); 408961b2408cSBarry Smith mxDestroyArray(plhs[0]); 409061b2408cSBarry Smith mxDestroyArray(plhs[1]); 409161b2408cSBarry Smith PetscFunctionReturn(0); 409261b2408cSBarry Smith } 409361b2408cSBarry Smith 409461b2408cSBarry Smith 409561b2408cSBarry Smith #undef __FUNCT__ 409661b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 409761b2408cSBarry Smith /* 409861b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 409961b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4100e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 410161b2408cSBarry Smith 410261b2408cSBarry Smith Logically Collective on SNES 410361b2408cSBarry Smith 410461b2408cSBarry Smith Input Parameters: 410561b2408cSBarry Smith + snes - the SNES context 410661b2408cSBarry Smith . A,B - Jacobian matrices 410761b2408cSBarry Smith . func - function evaluation routine 410861b2408cSBarry Smith - ctx - user context 410961b2408cSBarry Smith 411061b2408cSBarry Smith Calling sequence of func: 411161b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 411261b2408cSBarry Smith 411361b2408cSBarry Smith 411461b2408cSBarry Smith Level: developer 411561b2408cSBarry Smith 411661b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 411761b2408cSBarry Smith 411861b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 411961b2408cSBarry Smith */ 41207087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 412161b2408cSBarry Smith { 412261b2408cSBarry Smith PetscErrorCode ierr; 412361b2408cSBarry Smith SNESMatlabContext *sctx; 412461b2408cSBarry Smith 412561b2408cSBarry Smith PetscFunctionBegin; 412661b2408cSBarry Smith /* currently sctx is memory bleed */ 412761b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 412861b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 412961b2408cSBarry Smith /* 413061b2408cSBarry Smith This should work, but it doesn't 413161b2408cSBarry Smith sctx->ctx = ctx; 413261b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 413361b2408cSBarry Smith */ 413461b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 413561b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 413661b2408cSBarry Smith PetscFunctionReturn(0); 413761b2408cSBarry Smith } 413869b4f73cSBarry Smith 4139f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4140f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4141f9eb7ae2SShri Abhyankar /* 4142f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4143f9eb7ae2SShri Abhyankar 4144f9eb7ae2SShri Abhyankar Collective on SNES 4145f9eb7ae2SShri Abhyankar 4146f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4147f9eb7ae2SShri Abhyankar @*/ 41487087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4149f9eb7ae2SShri Abhyankar { 4150f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 415148f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4152f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4153f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4154f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4155f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4156f9eb7ae2SShri Abhyankar 4157f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4158f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4159f9eb7ae2SShri Abhyankar 4160f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4161f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4162f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4163f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4164f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4165f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4166f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4167f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4168f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4169f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4170f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4171f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4172f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4173f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4174f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4175f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4176f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4177f9eb7ae2SShri Abhyankar } 4178f9eb7ae2SShri Abhyankar 4179f9eb7ae2SShri Abhyankar 4180f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4181f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4182f9eb7ae2SShri Abhyankar /* 4183e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4184f9eb7ae2SShri Abhyankar 4185f9eb7ae2SShri Abhyankar Level: developer 4186f9eb7ae2SShri Abhyankar 4187f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4188f9eb7ae2SShri Abhyankar 4189f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4190f9eb7ae2SShri Abhyankar */ 41917087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4192f9eb7ae2SShri Abhyankar { 4193f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4194f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4195f9eb7ae2SShri Abhyankar 4196f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4197f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4198f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4199f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4200f9eb7ae2SShri Abhyankar /* 4201f9eb7ae2SShri Abhyankar This should work, but it doesn't 4202f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4203f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4204f9eb7ae2SShri Abhyankar */ 4205f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4206f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4207f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4208f9eb7ae2SShri Abhyankar } 4209f9eb7ae2SShri Abhyankar 421069b4f73cSBarry Smith #endif 4211