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) { 189eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D Newton 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 } 19694b7f48cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 197*4a0c5b0cSMatthew G Knepley if (snes->pc) { 198*4a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 199*4a0c5b0cSMatthew G Knepley ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr); 200*4a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 201*4a0c5b0cSMatthew G Knepley } 202b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 20394b7f48cSBarry Smith ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 204b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2053a40ed3dSBarry Smith PetscFunctionReturn(0); 2069b94acceSBarry Smith } 2079b94acceSBarry Smith 20876b2cf59SMatthew Knepley /* 20976b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 21076b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 21176b2cf59SMatthew Knepley */ 21276b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 213a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 2146849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 21576b2cf59SMatthew Knepley 216e74ef692SMatthew Knepley #undef __FUNCT__ 217e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker" 218ac226902SBarry Smith /*@C 21976b2cf59SMatthew Knepley SNESAddOptionsChecker - Adds an additional function to check for SNES options. 22076b2cf59SMatthew Knepley 22176b2cf59SMatthew Knepley Not Collective 22276b2cf59SMatthew Knepley 22376b2cf59SMatthew Knepley Input Parameter: 22476b2cf59SMatthew Knepley . snescheck - function that checks for options 22576b2cf59SMatthew Knepley 22676b2cf59SMatthew Knepley Level: developer 22776b2cf59SMatthew Knepley 22876b2cf59SMatthew Knepley .seealso: SNESSetFromOptions() 22976b2cf59SMatthew Knepley @*/ 2307087cfbeSBarry Smith PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 23176b2cf59SMatthew Knepley { 23276b2cf59SMatthew Knepley PetscFunctionBegin; 23376b2cf59SMatthew Knepley if (numberofsetfromoptions >= MAXSETFROMOPTIONS) { 234e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 23576b2cf59SMatthew Knepley } 23676b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 23776b2cf59SMatthew Knepley PetscFunctionReturn(0); 23876b2cf59SMatthew Knepley } 23976b2cf59SMatthew Knepley 2407087cfbeSBarry Smith extern PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 241aa3661deSLisandro Dalcin 242aa3661deSLisandro Dalcin #undef __FUNCT__ 243aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private" 244ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 245aa3661deSLisandro Dalcin { 246aa3661deSLisandro Dalcin Mat J; 247aa3661deSLisandro Dalcin KSP ksp; 248aa3661deSLisandro Dalcin PC pc; 249ace3abfcSBarry Smith PetscBool match; 250aa3661deSLisandro Dalcin PetscErrorCode ierr; 251aa3661deSLisandro Dalcin 252aa3661deSLisandro Dalcin PetscFunctionBegin; 2530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 254aa3661deSLisandro Dalcin 25598613b67SLisandro Dalcin if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 25698613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 25798613b67SLisandro Dalcin ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr); 25898613b67SLisandro Dalcin } 25998613b67SLisandro Dalcin 260aa3661deSLisandro Dalcin if (version == 1) { 261aa3661deSLisandro Dalcin ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 26298613b67SLisandro Dalcin ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 2639c6ac3b3SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 264aa3661deSLisandro Dalcin } else if (version == 2) { 265e32f2f54SBarry Smith if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 266ce63c4c1SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL_LONG_DOUBLE) 267aa3661deSLisandro Dalcin ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr); 268aa3661deSLisandro Dalcin #else 269e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)"); 270aa3661deSLisandro Dalcin #endif 271aa3661deSLisandro Dalcin } else { 272e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2"); 273aa3661deSLisandro Dalcin } 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 295aa3661deSLisandro Dalcin PetscFunctionReturn(0); 296aa3661deSLisandro Dalcin } 297aa3661deSLisandro Dalcin 2984a2ae208SSatish Balay #undef __FUNCT__ 2994a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions" 3009b94acceSBarry Smith /*@ 30194b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 3029b94acceSBarry Smith 303c7afd0dbSLois Curfman McInnes Collective on SNES 304c7afd0dbSLois Curfman McInnes 3059b94acceSBarry Smith Input Parameter: 3069b94acceSBarry Smith . snes - the SNES context 3079b94acceSBarry Smith 30836851e7fSLois Curfman McInnes Options Database Keys: 3096831982aSBarry Smith + -snes_type <type> - ls, tr, umls, umtr, test 31082738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 31182738288SBarry Smith of the change in the solution between steps 31270441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 313b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 314b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 315b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 31650ffb88aSMatthew Knepley . -snes_max_fail <max_fail> - maximum number of failures 317ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 318a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 319e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 320b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 3212492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 32282738288SBarry Smith solver; hence iterations will continue until max_it 3231fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 32482738288SBarry Smith of convergence test 325e8105e01SRichard Katz . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 326e8105e01SRichard Katz filename given prints to stdout 327a6570f20SBarry Smith . -snes_monitor_solution - plots solution at each iteration 328a6570f20SBarry Smith . -snes_monitor_residual - plots residual (not its norm) at each iteration 329a6570f20SBarry Smith . -snes_monitor_solution_update - plots update to solution at each iteration 330a6570f20SBarry Smith . -snes_monitor_draw - plots residual norm at each iteration 331e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 3325968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 333fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 33482738288SBarry Smith 33582738288SBarry Smith Options Database for Eisenstat-Walker method: 336fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 3374b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 33836851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 33936851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 34036851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 34136851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 34236851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 34336851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 34482738288SBarry Smith 34511ca99fdSLois Curfman McInnes Notes: 34611ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 3470598bfebSBarry Smith the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>. 34883e2fdc7SBarry Smith 34936851e7fSLois Curfman McInnes Level: beginner 35036851e7fSLois Curfman McInnes 3519b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 3529b94acceSBarry Smith 35369ed319cSSatish Balay .seealso: SNESSetOptionsPrefix() 3549b94acceSBarry Smith @*/ 3557087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 3569b94acceSBarry Smith { 357ace3abfcSBarry Smith PetscBool flg,mf,mf_operator; 358efd51863SBarry Smith PetscInt i,indx,lag,mf_version,grids; 359aa3661deSLisandro Dalcin MatStructure matflag; 36085385478SLisandro Dalcin const char *deft = SNESLS; 36185385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 36285385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 363e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 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);} 371cce0b1b2SLisandro Dalcin ierr = PetscOptionsBegin(((PetscObject)snes)->comm,((PetscObject)snes)->prefix,"Nonlinear solver (SNES) options","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 45490d69ab7SBarry Smith flg = PETSC_FALSE; 455acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 456a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 45790d69ab7SBarry Smith flg = PETSC_FALSE; 458acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 459a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 46090d69ab7SBarry Smith flg = PETSC_FALSE; 461acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 462a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 46390d69ab7SBarry Smith flg = PETSC_FALSE; 464acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 465a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 46690d69ab7SBarry Smith flg = PETSC_FALSE; 467acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 468b271bb04SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 469e24b481bSBarry Smith 47090d69ab7SBarry Smith flg = PETSC_FALSE; 471acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 4724b27c08aSLois Curfman McInnes if (flg) { 473186905e3SBarry Smith ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);CHKERRQ(ierr); 474ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 4759b94acceSBarry Smith } 476639f9d9dSBarry Smith 477aa3661deSLisandro Dalcin mf = mf_operator = PETSC_FALSE; 478aa3661deSLisandro Dalcin flg = PETSC_FALSE; 479acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr); 480aa3661deSLisandro Dalcin if (flg && mf_operator) mf = PETSC_TRUE; 481aa3661deSLisandro Dalcin flg = PETSC_FALSE; 482acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr); 483aa3661deSLisandro Dalcin if (!flg && mf_operator) mf = PETSC_TRUE; 484aa3661deSLisandro Dalcin mf_version = 1; 485aa3661deSLisandro Dalcin ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr); 486aa3661deSLisandro Dalcin 48776b2cf59SMatthew Knepley for(i = 0; i < numberofsetfromoptions; i++) { 48876b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 48976b2cf59SMatthew Knepley } 49076b2cf59SMatthew Knepley 491e7788613SBarry Smith if (snes->ops->setfromoptions) { 492e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 493639f9d9dSBarry Smith } 4945d973c19SBarry Smith 4955d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 4965d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 497b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 4984bbc92c1SBarry Smith 499aa3661deSLisandro Dalcin if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 5001cee3971SBarry Smith 5011cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 502aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 503aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 50485385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 50593993e2dSLois Curfman McInnes 506*4a0c5b0cSMatthew G Knepley if (snes->pc) { 507*4a0c5b0cSMatthew G Knepley ierr = SNESSetOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr); 508*4a0c5b0cSMatthew G Knepley ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 509*4a0c5b0cSMatthew G Knepley /* Should we make a duplicate vector and matrix? Leave the DM to make it? */ 510*4a0c5b0cSMatthew G Knepley ierr = SNESSetFunction(snes->pc, snes->vec_func, snes->ops->computefunction, snes->funP);CHKERRQ(ierr); 511*4a0c5b0cSMatthew G Knepley ierr = SNESSetJacobian(snes->pc, snes->jacobian, snes->jacobian_pre, snes->ops->computejacobian, snes->jacP);CHKERRQ(ierr); 512*4a0c5b0cSMatthew G Knepley ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 513*4a0c5b0cSMatthew G Knepley } 5143a40ed3dSBarry Smith PetscFunctionReturn(0); 5159b94acceSBarry Smith } 5169b94acceSBarry Smith 517d25893d9SBarry Smith #undef __FUNCT__ 518d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 519d25893d9SBarry Smith /*@ 520d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 521d25893d9SBarry Smith the nonlinear solvers. 522d25893d9SBarry Smith 523d25893d9SBarry Smith Logically Collective on SNES 524d25893d9SBarry Smith 525d25893d9SBarry Smith Input Parameters: 526d25893d9SBarry Smith + snes - the SNES context 527d25893d9SBarry Smith . compute - function to compute the context 528d25893d9SBarry Smith - destroy - function to destroy the context 529d25893d9SBarry Smith 530d25893d9SBarry Smith Level: intermediate 531d25893d9SBarry Smith 532d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 533d25893d9SBarry Smith 534d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 535d25893d9SBarry Smith @*/ 536d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 537d25893d9SBarry Smith { 538d25893d9SBarry Smith PetscFunctionBegin; 539d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 540d25893d9SBarry Smith snes->ops->usercompute = compute; 541d25893d9SBarry Smith snes->ops->userdestroy = destroy; 542d25893d9SBarry Smith PetscFunctionReturn(0); 543d25893d9SBarry Smith } 544a847f771SSatish Balay 5454a2ae208SSatish Balay #undef __FUNCT__ 5464a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 547b07ff414SBarry Smith /*@ 5489b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 5499b94acceSBarry Smith the nonlinear solvers. 5509b94acceSBarry Smith 5513f9fe445SBarry Smith Logically Collective on SNES 552fee21e36SBarry Smith 553c7afd0dbSLois Curfman McInnes Input Parameters: 554c7afd0dbSLois Curfman McInnes + snes - the SNES context 555c7afd0dbSLois Curfman McInnes - usrP - optional user context 556c7afd0dbSLois Curfman McInnes 55736851e7fSLois Curfman McInnes Level: intermediate 55836851e7fSLois Curfman McInnes 5599b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 5609b94acceSBarry Smith 561d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext() 5629b94acceSBarry Smith @*/ 5637087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 5649b94acceSBarry Smith { 5651b2093e4SBarry Smith PetscErrorCode ierr; 566b07ff414SBarry Smith KSP ksp; 5671b2093e4SBarry Smith 5683a40ed3dSBarry Smith PetscFunctionBegin; 5690700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 570b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 571b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 5729b94acceSBarry Smith snes->user = usrP; 5733a40ed3dSBarry Smith PetscFunctionReturn(0); 5749b94acceSBarry Smith } 57574679c65SBarry Smith 5764a2ae208SSatish Balay #undef __FUNCT__ 5774a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 578b07ff414SBarry Smith /*@ 5799b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 5809b94acceSBarry Smith nonlinear solvers. 5819b94acceSBarry Smith 582c7afd0dbSLois Curfman McInnes Not Collective 583c7afd0dbSLois Curfman McInnes 5849b94acceSBarry Smith Input Parameter: 5859b94acceSBarry Smith . snes - SNES context 5869b94acceSBarry Smith 5879b94acceSBarry Smith Output Parameter: 5889b94acceSBarry Smith . usrP - user context 5899b94acceSBarry Smith 59036851e7fSLois Curfman McInnes Level: intermediate 59136851e7fSLois Curfman McInnes 5929b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 5939b94acceSBarry Smith 5949b94acceSBarry Smith .seealso: SNESSetApplicationContext() 5959b94acceSBarry Smith @*/ 5967087cfbeSBarry Smith PetscErrorCode SNESGetApplicationContext(SNES snes,void **usrP) 5979b94acceSBarry Smith { 5983a40ed3dSBarry Smith PetscFunctionBegin; 5990700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 6009b94acceSBarry Smith *usrP = snes->user; 6013a40ed3dSBarry Smith PetscFunctionReturn(0); 6029b94acceSBarry Smith } 60374679c65SBarry Smith 6044a2ae208SSatish Balay #undef __FUNCT__ 6054a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 6069b94acceSBarry Smith /*@ 607c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 608c8228a4eSBarry Smith at this time. 6099b94acceSBarry Smith 610c7afd0dbSLois Curfman McInnes Not Collective 611c7afd0dbSLois Curfman McInnes 6129b94acceSBarry Smith Input Parameter: 6139b94acceSBarry Smith . snes - SNES context 6149b94acceSBarry Smith 6159b94acceSBarry Smith Output Parameter: 6169b94acceSBarry Smith . iter - iteration number 6179b94acceSBarry Smith 618c8228a4eSBarry Smith Notes: 619c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 620c8228a4eSBarry Smith 621c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 62208405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 62308405cd6SLois Curfman McInnes .vb 62408405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 62508405cd6SLois Curfman McInnes if (!(it % 2)) { 62608405cd6SLois Curfman McInnes [compute Jacobian here] 62708405cd6SLois Curfman McInnes } 62808405cd6SLois Curfman McInnes .ve 629c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 63008405cd6SLois Curfman McInnes recomputed every second SNES iteration. 631c8228a4eSBarry Smith 63236851e7fSLois Curfman McInnes Level: intermediate 63336851e7fSLois Curfman McInnes 6342b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 6352b668275SBarry Smith 636b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 6379b94acceSBarry Smith @*/ 6387087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 6399b94acceSBarry Smith { 6403a40ed3dSBarry Smith PetscFunctionBegin; 6410700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 6424482741eSBarry Smith PetscValidIntPointer(iter,2); 6439b94acceSBarry Smith *iter = snes->iter; 6443a40ed3dSBarry Smith PetscFunctionReturn(0); 6459b94acceSBarry Smith } 64674679c65SBarry Smith 6474a2ae208SSatish Balay #undef __FUNCT__ 6484a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 6499b94acceSBarry Smith /*@ 6509b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 6519b94acceSBarry Smith with SNESSSetFunction(). 6529b94acceSBarry Smith 653c7afd0dbSLois Curfman McInnes Collective on SNES 654c7afd0dbSLois Curfman McInnes 6559b94acceSBarry Smith Input Parameter: 6569b94acceSBarry Smith . snes - SNES context 6579b94acceSBarry Smith 6589b94acceSBarry Smith Output Parameter: 6599b94acceSBarry Smith . fnorm - 2-norm of function 6609b94acceSBarry Smith 66136851e7fSLois Curfman McInnes Level: intermediate 66236851e7fSLois Curfman McInnes 6639b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 664a86d99e1SLois Curfman McInnes 665b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 6669b94acceSBarry Smith @*/ 6677087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 6689b94acceSBarry Smith { 6693a40ed3dSBarry Smith PetscFunctionBegin; 6700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 6714482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 6729b94acceSBarry Smith *fnorm = snes->norm; 6733a40ed3dSBarry Smith PetscFunctionReturn(0); 6749b94acceSBarry Smith } 67574679c65SBarry Smith 6764a2ae208SSatish Balay #undef __FUNCT__ 677b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 6789b94acceSBarry Smith /*@ 679b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 6809b94acceSBarry Smith attempted by the nonlinear solver. 6819b94acceSBarry Smith 682c7afd0dbSLois Curfman McInnes Not Collective 683c7afd0dbSLois Curfman McInnes 6849b94acceSBarry Smith Input Parameter: 6859b94acceSBarry Smith . snes - SNES context 6869b94acceSBarry Smith 6879b94acceSBarry Smith Output Parameter: 6889b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 6899b94acceSBarry Smith 690c96a6f78SLois Curfman McInnes Notes: 691c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 692c96a6f78SLois Curfman McInnes 69336851e7fSLois Curfman McInnes Level: intermediate 69436851e7fSLois Curfman McInnes 6959b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 69658ebbce7SBarry Smith 697e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 69858ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 6999b94acceSBarry Smith @*/ 7007087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 7019b94acceSBarry Smith { 7023a40ed3dSBarry Smith PetscFunctionBegin; 7030700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7044482741eSBarry Smith PetscValidIntPointer(nfails,2); 70550ffb88aSMatthew Knepley *nfails = snes->numFailures; 70650ffb88aSMatthew Knepley PetscFunctionReturn(0); 70750ffb88aSMatthew Knepley } 70850ffb88aSMatthew Knepley 70950ffb88aSMatthew Knepley #undef __FUNCT__ 710b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 71150ffb88aSMatthew Knepley /*@ 712b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 71350ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 71450ffb88aSMatthew Knepley 71550ffb88aSMatthew Knepley Not Collective 71650ffb88aSMatthew Knepley 71750ffb88aSMatthew Knepley Input Parameters: 71850ffb88aSMatthew Knepley + snes - SNES context 71950ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 72050ffb88aSMatthew Knepley 72150ffb88aSMatthew Knepley Level: intermediate 72250ffb88aSMatthew Knepley 72350ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 72458ebbce7SBarry Smith 725e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 72658ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 72750ffb88aSMatthew Knepley @*/ 7287087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 72950ffb88aSMatthew Knepley { 73050ffb88aSMatthew Knepley PetscFunctionBegin; 7310700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 73250ffb88aSMatthew Knepley snes->maxFailures = maxFails; 73350ffb88aSMatthew Knepley PetscFunctionReturn(0); 73450ffb88aSMatthew Knepley } 73550ffb88aSMatthew Knepley 73650ffb88aSMatthew Knepley #undef __FUNCT__ 737b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 73850ffb88aSMatthew Knepley /*@ 739b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 74050ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 74150ffb88aSMatthew Knepley 74250ffb88aSMatthew Knepley Not Collective 74350ffb88aSMatthew Knepley 74450ffb88aSMatthew Knepley Input Parameter: 74550ffb88aSMatthew Knepley . snes - SNES context 74650ffb88aSMatthew Knepley 74750ffb88aSMatthew Knepley Output Parameter: 74850ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 74950ffb88aSMatthew Knepley 75050ffb88aSMatthew Knepley Level: intermediate 75150ffb88aSMatthew Knepley 75250ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 75358ebbce7SBarry Smith 754e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 75558ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 75658ebbce7SBarry Smith 75750ffb88aSMatthew Knepley @*/ 7587087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 75950ffb88aSMatthew Knepley { 76050ffb88aSMatthew Knepley PetscFunctionBegin; 7610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7624482741eSBarry Smith PetscValidIntPointer(maxFails,2); 76350ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 7643a40ed3dSBarry Smith PetscFunctionReturn(0); 7659b94acceSBarry Smith } 766a847f771SSatish Balay 7674a2ae208SSatish Balay #undef __FUNCT__ 7682541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 7692541af92SBarry Smith /*@ 7702541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 7712541af92SBarry Smith done by SNES. 7722541af92SBarry Smith 7732541af92SBarry Smith Not Collective 7742541af92SBarry Smith 7752541af92SBarry Smith Input Parameter: 7762541af92SBarry Smith . snes - SNES context 7772541af92SBarry Smith 7782541af92SBarry Smith Output Parameter: 7792541af92SBarry Smith . nfuncs - number of evaluations 7802541af92SBarry Smith 7812541af92SBarry Smith Level: intermediate 7822541af92SBarry Smith 7832541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 78458ebbce7SBarry Smith 785e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 7862541af92SBarry Smith @*/ 7877087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 7882541af92SBarry Smith { 7892541af92SBarry Smith PetscFunctionBegin; 7900700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7912541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 7922541af92SBarry Smith *nfuncs = snes->nfuncs; 7932541af92SBarry Smith PetscFunctionReturn(0); 7942541af92SBarry Smith } 7952541af92SBarry Smith 7962541af92SBarry Smith #undef __FUNCT__ 7973d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 7983d4c4710SBarry Smith /*@ 7993d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 8003d4c4710SBarry Smith linear solvers. 8013d4c4710SBarry Smith 8023d4c4710SBarry Smith Not Collective 8033d4c4710SBarry Smith 8043d4c4710SBarry Smith Input Parameter: 8053d4c4710SBarry Smith . snes - SNES context 8063d4c4710SBarry Smith 8073d4c4710SBarry Smith Output Parameter: 8083d4c4710SBarry Smith . nfails - number of failed solves 8093d4c4710SBarry Smith 8103d4c4710SBarry Smith Notes: 8113d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 8123d4c4710SBarry Smith 8133d4c4710SBarry Smith Level: intermediate 8143d4c4710SBarry Smith 8153d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 81658ebbce7SBarry Smith 817e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 8183d4c4710SBarry Smith @*/ 8197087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 8203d4c4710SBarry Smith { 8213d4c4710SBarry Smith PetscFunctionBegin; 8220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8233d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 8243d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 8253d4c4710SBarry Smith PetscFunctionReturn(0); 8263d4c4710SBarry Smith } 8273d4c4710SBarry Smith 8283d4c4710SBarry Smith #undef __FUNCT__ 8293d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 8303d4c4710SBarry Smith /*@ 8313d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 8323d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 8333d4c4710SBarry Smith 8343f9fe445SBarry Smith Logically Collective on SNES 8353d4c4710SBarry Smith 8363d4c4710SBarry Smith Input Parameters: 8373d4c4710SBarry Smith + snes - SNES context 8383d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 8393d4c4710SBarry Smith 8403d4c4710SBarry Smith Level: intermediate 8413d4c4710SBarry Smith 842a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 8433d4c4710SBarry Smith 8443d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 8453d4c4710SBarry Smith 84658ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 8473d4c4710SBarry Smith @*/ 8487087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 8493d4c4710SBarry Smith { 8503d4c4710SBarry Smith PetscFunctionBegin; 8510700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 852c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 8533d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 8543d4c4710SBarry Smith PetscFunctionReturn(0); 8553d4c4710SBarry Smith } 8563d4c4710SBarry Smith 8573d4c4710SBarry Smith #undef __FUNCT__ 8583d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 8593d4c4710SBarry Smith /*@ 8603d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 8613d4c4710SBarry Smith are allowed before SNES terminates 8623d4c4710SBarry Smith 8633d4c4710SBarry Smith Not Collective 8643d4c4710SBarry Smith 8653d4c4710SBarry Smith Input Parameter: 8663d4c4710SBarry Smith . snes - SNES context 8673d4c4710SBarry Smith 8683d4c4710SBarry Smith Output Parameter: 8693d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 8703d4c4710SBarry Smith 8713d4c4710SBarry Smith Level: intermediate 8723d4c4710SBarry Smith 8733d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 8743d4c4710SBarry Smith 8753d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 8763d4c4710SBarry Smith 877e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 8783d4c4710SBarry Smith @*/ 8797087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 8803d4c4710SBarry Smith { 8813d4c4710SBarry Smith PetscFunctionBegin; 8820700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8833d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 8843d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 8853d4c4710SBarry Smith PetscFunctionReturn(0); 8863d4c4710SBarry Smith } 8873d4c4710SBarry Smith 8883d4c4710SBarry Smith #undef __FUNCT__ 889b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 890c96a6f78SLois Curfman McInnes /*@ 891b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 892c96a6f78SLois Curfman McInnes used by the nonlinear solver. 893c96a6f78SLois Curfman McInnes 894c7afd0dbSLois Curfman McInnes Not Collective 895c7afd0dbSLois Curfman McInnes 896c96a6f78SLois Curfman McInnes Input Parameter: 897c96a6f78SLois Curfman McInnes . snes - SNES context 898c96a6f78SLois Curfman McInnes 899c96a6f78SLois Curfman McInnes Output Parameter: 900c96a6f78SLois Curfman McInnes . lits - number of linear iterations 901c96a6f78SLois Curfman McInnes 902c96a6f78SLois Curfman McInnes Notes: 903c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 904c96a6f78SLois Curfman McInnes 90536851e7fSLois Curfman McInnes Level: intermediate 90636851e7fSLois Curfman McInnes 907c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 9082b668275SBarry Smith 9098c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 910c96a6f78SLois Curfman McInnes @*/ 9117087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 912c96a6f78SLois Curfman McInnes { 9133a40ed3dSBarry Smith PetscFunctionBegin; 9140700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9154482741eSBarry Smith PetscValidIntPointer(lits,2); 916c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 9173a40ed3dSBarry Smith PetscFunctionReturn(0); 918c96a6f78SLois Curfman McInnes } 919c96a6f78SLois Curfman McInnes 9204a2ae208SSatish Balay #undef __FUNCT__ 92194b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 92252baeb72SSatish Balay /*@ 92394b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 9249b94acceSBarry Smith 92594b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 926c7afd0dbSLois Curfman McInnes 9279b94acceSBarry Smith Input Parameter: 9289b94acceSBarry Smith . snes - the SNES context 9299b94acceSBarry Smith 9309b94acceSBarry Smith Output Parameter: 93194b7f48cSBarry Smith . ksp - the KSP context 9329b94acceSBarry Smith 9339b94acceSBarry Smith Notes: 93494b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 9359b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 9362999313aSBarry Smith PC contexts as well. 9379b94acceSBarry Smith 93836851e7fSLois Curfman McInnes Level: beginner 93936851e7fSLois Curfman McInnes 94094b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 9419b94acceSBarry Smith 9422999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 9439b94acceSBarry Smith @*/ 9447087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 9459b94acceSBarry Smith { 9461cee3971SBarry Smith PetscErrorCode ierr; 9471cee3971SBarry Smith 9483a40ed3dSBarry Smith PetscFunctionBegin; 9490700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9504482741eSBarry Smith PetscValidPointer(ksp,2); 9511cee3971SBarry Smith 9521cee3971SBarry Smith if (!snes->ksp) { 9531cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 9541cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 9551cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 9561cee3971SBarry Smith } 95794b7f48cSBarry Smith *ksp = snes->ksp; 9583a40ed3dSBarry Smith PetscFunctionReturn(0); 9599b94acceSBarry Smith } 96082bf6240SBarry Smith 9614a2ae208SSatish Balay #undef __FUNCT__ 9622999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 9632999313aSBarry Smith /*@ 9642999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 9652999313aSBarry Smith 9662999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 9672999313aSBarry Smith 9682999313aSBarry Smith Input Parameters: 9692999313aSBarry Smith + snes - the SNES context 9702999313aSBarry Smith - ksp - the KSP context 9712999313aSBarry Smith 9722999313aSBarry Smith Notes: 9732999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 9742999313aSBarry Smith so this routine is rarely needed. 9752999313aSBarry Smith 9762999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 9772999313aSBarry Smith decreased by one. 9782999313aSBarry Smith 9792999313aSBarry Smith Level: developer 9802999313aSBarry Smith 9812999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 9822999313aSBarry Smith 9832999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 9842999313aSBarry Smith @*/ 9857087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 9862999313aSBarry Smith { 9872999313aSBarry Smith PetscErrorCode ierr; 9882999313aSBarry Smith 9892999313aSBarry Smith PetscFunctionBegin; 9900700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9910700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 9922999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 9937dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 994906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 9952999313aSBarry Smith snes->ksp = ksp; 9962999313aSBarry Smith PetscFunctionReturn(0); 9972999313aSBarry Smith } 9982999313aSBarry Smith 9997adad957SLisandro Dalcin #if 0 10002999313aSBarry Smith #undef __FUNCT__ 10014a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 10026849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1003e24b481bSBarry Smith { 1004e24b481bSBarry Smith PetscFunctionBegin; 1005e24b481bSBarry Smith PetscFunctionReturn(0); 1006e24b481bSBarry Smith } 10077adad957SLisandro Dalcin #endif 1008e24b481bSBarry Smith 10099b94acceSBarry Smith /* -----------------------------------------------------------*/ 10104a2ae208SSatish Balay #undef __FUNCT__ 10114a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 101252baeb72SSatish Balay /*@ 10139b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 10149b94acceSBarry Smith 1015c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1016c7afd0dbSLois Curfman McInnes 1017c7afd0dbSLois Curfman McInnes Input Parameters: 1018906ed7ccSBarry Smith . comm - MPI communicator 10199b94acceSBarry Smith 10209b94acceSBarry Smith Output Parameter: 10219b94acceSBarry Smith . outsnes - the new SNES context 10229b94acceSBarry Smith 1023c7afd0dbSLois Curfman McInnes Options Database Keys: 1024c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1025c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1026c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1027c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1028c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1029c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1030c1f60f51SBarry Smith 103136851e7fSLois Curfman McInnes Level: beginner 103236851e7fSLois Curfman McInnes 10339b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 10349b94acceSBarry Smith 1035a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1036a8054027SBarry Smith 10379b94acceSBarry Smith @*/ 10387087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 10399b94acceSBarry Smith { 1040dfbe8321SBarry Smith PetscErrorCode ierr; 10419b94acceSBarry Smith SNES snes; 1042fa9f3622SBarry Smith SNESKSPEW *kctx; 104337fcc0dbSBarry Smith 10443a40ed3dSBarry Smith PetscFunctionBegin; 1045ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 10468ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 10478ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 10488ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 10498ba1e511SMatthew Knepley #endif 10508ba1e511SMatthew Knepley 10510700a824SBarry Smith ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 10527adad957SLisandro Dalcin 105385385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 10549b94acceSBarry Smith snes->max_its = 50; 10559750a799SBarry Smith snes->max_funcs = 10000; 10569b94acceSBarry Smith snes->norm = 0.0; 1057b4874afaSBarry Smith snes->rtol = 1.e-8; 1058b4874afaSBarry Smith snes->ttol = 0.0; 105970441072SBarry Smith snes->abstol = 1.e-50; 10609b94acceSBarry Smith snes->xtol = 1.e-8; 10614b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 10629b94acceSBarry Smith snes->nfuncs = 0; 106350ffb88aSMatthew Knepley snes->numFailures = 0; 106450ffb88aSMatthew Knepley snes->maxFailures = 1; 10657a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1066e35cf81dSBarry Smith snes->lagjacobian = 1; 1067a8054027SBarry Smith snes->lagpreconditioner = 1; 1068639f9d9dSBarry Smith snes->numbermonitors = 0; 10699b94acceSBarry Smith snes->data = 0; 10704dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1071186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 10726f24a144SLois Curfman McInnes snes->nwork = 0; 107358c9b817SLisandro Dalcin snes->work = 0; 107458c9b817SLisandro Dalcin snes->nvwork = 0; 107558c9b817SLisandro Dalcin snes->vwork = 0; 1076758f92a0SBarry Smith snes->conv_hist_len = 0; 1077758f92a0SBarry Smith snes->conv_hist_max = 0; 1078758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1079758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1080758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1081184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 10829b94acceSBarry Smith 10833d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 10843d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 10853d4c4710SBarry Smith 10869b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 108738f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 10889b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 10899b94acceSBarry Smith kctx->version = 2; 10909b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 10919b94acceSBarry Smith this was too large for some test cases */ 109275567043SBarry Smith kctx->rtol_last = 0.0; 10939b94acceSBarry Smith kctx->rtol_max = .9; 10949b94acceSBarry Smith kctx->gamma = 1.0; 109571f87433Sdalcinl kctx->alpha = .5*(1.0 + sqrt(5.0)); 109671f87433Sdalcinl kctx->alpha2 = kctx->alpha; 10979b94acceSBarry Smith kctx->threshold = .1; 109875567043SBarry Smith kctx->lresid_last = 0.0; 109975567043SBarry Smith kctx->norm_last = 0.0; 11009b94acceSBarry Smith 11019b94acceSBarry Smith *outsnes = snes; 11023a40ed3dSBarry Smith PetscFunctionReturn(0); 11039b94acceSBarry Smith } 11049b94acceSBarry Smith 11054a2ae208SSatish Balay #undef __FUNCT__ 11064a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 11079b94acceSBarry Smith /*@C 11089b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 11099b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 11109b94acceSBarry Smith equations. 11119b94acceSBarry Smith 11123f9fe445SBarry Smith Logically Collective on SNES 1113fee21e36SBarry Smith 1114c7afd0dbSLois Curfman McInnes Input Parameters: 1115c7afd0dbSLois Curfman McInnes + snes - the SNES context 1116c7afd0dbSLois Curfman McInnes . r - vector to store function value 1117de044059SHong Zhang . func - function evaluation routine 1118c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1119c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 11209b94acceSBarry Smith 1121c7afd0dbSLois Curfman McInnes Calling sequence of func: 11228d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1123c7afd0dbSLois Curfman McInnes 1124313e4042SLois Curfman McInnes . f - function vector 1125c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 11269b94acceSBarry Smith 11279b94acceSBarry Smith Notes: 11289b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 11299b94acceSBarry Smith $ f'(x) x = -f(x), 1130c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 11319b94acceSBarry Smith 113236851e7fSLois Curfman McInnes Level: beginner 113336851e7fSLois Curfman McInnes 11349b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 11359b94acceSBarry Smith 1136a86d99e1SLois Curfman McInnes .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 11379b94acceSBarry Smith @*/ 11387087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 11399b94acceSBarry Smith { 114085385478SLisandro Dalcin PetscErrorCode ierr; 11413a40ed3dSBarry Smith PetscFunctionBegin; 11420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1143d2a683ecSLisandro Dalcin if (r) { 1144d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1145d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 114685385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 11476bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 114885385478SLisandro Dalcin snes->vec_func = r; 1149d2a683ecSLisandro Dalcin } else if (!snes->vec_func && snes->dm) { 1150d2a683ecSLisandro Dalcin ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 1151d2a683ecSLisandro Dalcin } 1152d2a683ecSLisandro Dalcin if (func) snes->ops->computefunction = func; 1153d2a683ecSLisandro Dalcin if (ctx) snes->funP = ctx; 11543a40ed3dSBarry Smith PetscFunctionReturn(0); 11559b94acceSBarry Smith } 11569b94acceSBarry Smith 1157d25893d9SBarry Smith #undef __FUNCT__ 1158d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1159d25893d9SBarry Smith /*@C 1160d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1161d25893d9SBarry Smith 1162d25893d9SBarry Smith Logically Collective on SNES 1163d25893d9SBarry Smith 1164d25893d9SBarry Smith Input Parameters: 1165d25893d9SBarry Smith + snes - the SNES context 1166d25893d9SBarry Smith . func - function evaluation routine 1167d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1168d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1169d25893d9SBarry Smith 1170d25893d9SBarry Smith Calling sequence of func: 1171d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1172d25893d9SBarry Smith 1173d25893d9SBarry Smith . f - function vector 1174d25893d9SBarry Smith - ctx - optional user-defined function context 1175d25893d9SBarry Smith 1176d25893d9SBarry Smith Level: intermediate 1177d25893d9SBarry Smith 1178d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1179d25893d9SBarry Smith 1180d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1181d25893d9SBarry Smith @*/ 1182d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1183d25893d9SBarry Smith { 1184d25893d9SBarry Smith PetscFunctionBegin; 1185d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1186d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1187d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1188d25893d9SBarry Smith PetscFunctionReturn(0); 1189d25893d9SBarry Smith } 1190d25893d9SBarry Smith 11913ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 11923ab0aad5SBarry Smith #undef __FUNCT__ 11931096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 11941096aae1SMatthew Knepley /*@C 11951096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 11961096aae1SMatthew Knepley it assumes a zero right hand side. 11971096aae1SMatthew Knepley 11983f9fe445SBarry Smith Logically Collective on SNES 11991096aae1SMatthew Knepley 12001096aae1SMatthew Knepley Input Parameter: 12011096aae1SMatthew Knepley . snes - the SNES context 12021096aae1SMatthew Knepley 12031096aae1SMatthew Knepley Output Parameter: 1204bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 12051096aae1SMatthew Knepley 12061096aae1SMatthew Knepley Level: intermediate 12071096aae1SMatthew Knepley 12081096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 12091096aae1SMatthew Knepley 121085385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 12111096aae1SMatthew Knepley @*/ 12127087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 12131096aae1SMatthew Knepley { 12141096aae1SMatthew Knepley PetscFunctionBegin; 12150700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12161096aae1SMatthew Knepley PetscValidPointer(rhs,2); 121785385478SLisandro Dalcin *rhs = snes->vec_rhs; 12181096aae1SMatthew Knepley PetscFunctionReturn(0); 12191096aae1SMatthew Knepley } 12201096aae1SMatthew Knepley 12211096aae1SMatthew Knepley #undef __FUNCT__ 12224a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 12239b94acceSBarry Smith /*@ 122436851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 12259b94acceSBarry Smith SNESSetFunction(). 12269b94acceSBarry Smith 1227c7afd0dbSLois Curfman McInnes Collective on SNES 1228c7afd0dbSLois Curfman McInnes 12299b94acceSBarry Smith Input Parameters: 1230c7afd0dbSLois Curfman McInnes + snes - the SNES context 1231c7afd0dbSLois Curfman McInnes - x - input vector 12329b94acceSBarry Smith 12339b94acceSBarry Smith Output Parameter: 12343638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 12359b94acceSBarry Smith 12361bffabb2SLois Curfman McInnes Notes: 123736851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 123836851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 123936851e7fSLois Curfman McInnes themselves. 124036851e7fSLois Curfman McInnes 124136851e7fSLois Curfman McInnes Level: developer 124236851e7fSLois Curfman McInnes 12439b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 12449b94acceSBarry Smith 1245a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 12469b94acceSBarry Smith @*/ 12477087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 12489b94acceSBarry Smith { 1249dfbe8321SBarry Smith PetscErrorCode ierr; 12509b94acceSBarry Smith 12513a40ed3dSBarry Smith PetscFunctionBegin; 12520700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12530700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 12540700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1255c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1256c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 1257184914b5SBarry Smith 1258d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 1259e7788613SBarry Smith if (snes->ops->computefunction) { 1260d64ed03dSBarry Smith PetscStackPush("SNES user function"); 126139d508bbSBarry Smith ierr = (*snes->ops->computefunction)(snes,x,y,snes->funP);CHKERRQ(ierr); 1262d64ed03dSBarry Smith PetscStackPop; 126385385478SLisandro Dalcin } else if (snes->vec_rhs) { 12641096aae1SMatthew Knepley ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 126573250ac0SBarry Smith } else if (snes->dm) { 1266644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1267644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 126885385478SLisandro Dalcin if (snes->vec_rhs) { 126985385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 12703ab0aad5SBarry Smith } 1271ae3c334cSLois Curfman McInnes snes->nfuncs++; 1272d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 12733a40ed3dSBarry Smith PetscFunctionReturn(0); 12749b94acceSBarry Smith } 12759b94acceSBarry Smith 12764a2ae208SSatish Balay #undef __FUNCT__ 12774a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 127862fef451SLois Curfman McInnes /*@ 127962fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 128062fef451SLois Curfman McInnes set with SNESSetJacobian(). 128162fef451SLois Curfman McInnes 1282c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1283c7afd0dbSLois Curfman McInnes 128462fef451SLois Curfman McInnes Input Parameters: 1285c7afd0dbSLois Curfman McInnes + snes - the SNES context 1286c7afd0dbSLois Curfman McInnes - x - input vector 128762fef451SLois Curfman McInnes 128862fef451SLois Curfman McInnes Output Parameters: 1289c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 129062fef451SLois Curfman McInnes . B - optional preconditioning matrix 12912b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1292fee21e36SBarry Smith 1293e35cf81dSBarry Smith Options Database Keys: 1294e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1295693365a8SJed Brown . -snes_lag_jacobian <lag> 1296693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1297693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1298693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 1299693365a8SJed Brown - -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1300e35cf81dSBarry Smith 130162fef451SLois Curfman McInnes Notes: 130262fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 130362fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 130462fef451SLois Curfman McInnes 130594b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1306dc5a77f8SLois Curfman McInnes flag parameter. 130762fef451SLois Curfman McInnes 130836851e7fSLois Curfman McInnes Level: developer 130936851e7fSLois Curfman McInnes 131062fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 131162fef451SLois Curfman McInnes 1312e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 131362fef451SLois Curfman McInnes @*/ 13147087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 13159b94acceSBarry Smith { 1316dfbe8321SBarry Smith PetscErrorCode ierr; 1317ace3abfcSBarry Smith PetscBool flag; 13183a40ed3dSBarry Smith 13193a40ed3dSBarry Smith PetscFunctionBegin; 13200700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13210700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 13224482741eSBarry Smith PetscValidPointer(flg,5); 1323c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 1324e7788613SBarry Smith if (!snes->ops->computejacobian) PetscFunctionReturn(0); 1325ebd3b9afSBarry Smith 1326ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1327ebd3b9afSBarry Smith 1328fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 1329fe3ffe1eSBarry Smith snes->lagjacobian = -1; 1330fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1331fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 1332e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1333e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1334ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1335ebd3b9afSBarry Smith if (flag) { 1336ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1337ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1338ebd3b9afSBarry Smith } 1339e35cf81dSBarry Smith PetscFunctionReturn(0); 1340e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1341e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1342e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1343ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1344ebd3b9afSBarry Smith if (flag) { 1345ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1346ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1347ebd3b9afSBarry Smith } 1348e35cf81dSBarry Smith PetscFunctionReturn(0); 1349e35cf81dSBarry Smith } 1350e35cf81dSBarry Smith 1351c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 1352e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1353d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 1354e7788613SBarry Smith ierr = (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);CHKERRQ(ierr); 1355d64ed03dSBarry Smith PetscStackPop; 1356d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1357a8054027SBarry Smith 13583b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 13593b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 13603b4f5425SBarry Smith snes->lagpreconditioner = -1; 13613b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 1362a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1363a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 1364a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 1365a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1366a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 1367a8054027SBarry Smith } 1368a8054027SBarry Smith 13696d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 13700700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 13710700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 1372693365a8SJed Brown { 1373693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 1374693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 1375693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 1376693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 1377693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 1378693365a8SJed Brown if (flag || flag_draw || flag_contour) { 1379693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 1380693365a8SJed Brown MatStructure mstruct; 1381693365a8SJed Brown PetscViewer vdraw,vstdout; 13826b3a5b13SJed Brown PetscBool flg; 1383693365a8SJed Brown if (flag_operator) { 1384693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 1385693365a8SJed Brown Bexp = Bexp_mine; 1386693365a8SJed Brown } else { 1387693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 1388693365a8SJed Brown ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 1389693365a8SJed Brown if (flg) Bexp = *B; 1390693365a8SJed Brown else { 1391693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 1392693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 1393693365a8SJed Brown Bexp = Bexp_mine; 1394693365a8SJed Brown } 1395693365a8SJed Brown } 1396693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 1397693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 1398693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 1399693365a8SJed Brown if (flag_draw || flag_contour) { 1400693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 1401693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 1402693365a8SJed Brown } else vdraw = PETSC_NULL; 1403693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 1404693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 1405693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 1406693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 1407693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1408693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 1409693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1410693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 1411693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1412693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 1413693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 1414693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 1415693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 1416693365a8SJed Brown } 1417693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 1418693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 1419693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 1420693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 1421693365a8SJed Brown } 1422693365a8SJed Brown } 14233a40ed3dSBarry Smith PetscFunctionReturn(0); 14249b94acceSBarry Smith } 14259b94acceSBarry Smith 14264a2ae208SSatish Balay #undef __FUNCT__ 14274a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 14289b94acceSBarry Smith /*@C 14299b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 1430044dda88SLois Curfman McInnes location to store the matrix. 14319b94acceSBarry Smith 14323f9fe445SBarry Smith Logically Collective on SNES and Mat 1433c7afd0dbSLois Curfman McInnes 14349b94acceSBarry Smith Input Parameters: 1435c7afd0dbSLois Curfman McInnes + snes - the SNES context 14369b94acceSBarry Smith . A - Jacobian matrix 14379b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 1438efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 1439c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1440efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 14419b94acceSBarry Smith 14429b94acceSBarry Smith Calling sequence of func: 14438d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 14449b94acceSBarry Smith 1445c7afd0dbSLois Curfman McInnes + x - input vector 14469b94acceSBarry Smith . A - Jacobian matrix 14479b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 1448ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 14492b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 1450c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 14519b94acceSBarry Smith 14529b94acceSBarry Smith Notes: 145394b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 14542cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 1455ac21db08SLois Curfman McInnes 1456ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 14579b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 14589b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 14599b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 14609b94acceSBarry Smith throughout the global iterations. 14619b94acceSBarry Smith 146216913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 146316913363SBarry Smith each matrix. 146416913363SBarry Smith 1465a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 1466a8a26c1eSJed Brown must be a MatFDColoring. 1467a8a26c1eSJed Brown 146836851e7fSLois Curfman McInnes Level: beginner 146936851e7fSLois Curfman McInnes 14709b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 14719b94acceSBarry Smith 14723ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 14739b94acceSBarry Smith @*/ 14747087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 14759b94acceSBarry Smith { 1476dfbe8321SBarry Smith PetscErrorCode ierr; 14773a7fca6bSBarry Smith 14783a40ed3dSBarry Smith PetscFunctionBegin; 14790700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14800700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 14810700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 1482c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 148306975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 1484e7788613SBarry Smith if (func) snes->ops->computejacobian = func; 14853a7fca6bSBarry Smith if (ctx) snes->jacP = ctx; 14863a7fca6bSBarry Smith if (A) { 14877dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 14886bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 14899b94acceSBarry Smith snes->jacobian = A; 14903a7fca6bSBarry Smith } 14913a7fca6bSBarry Smith if (B) { 14927dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 14936bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 14949b94acceSBarry Smith snes->jacobian_pre = B; 14953a7fca6bSBarry Smith } 14963a40ed3dSBarry Smith PetscFunctionReturn(0); 14979b94acceSBarry Smith } 149862fef451SLois Curfman McInnes 14994a2ae208SSatish Balay #undef __FUNCT__ 15004a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 1501c2aafc4cSSatish Balay /*@C 1502b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 1503b4fd4287SBarry Smith provided context for evaluating the Jacobian. 1504b4fd4287SBarry Smith 1505c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 1506c7afd0dbSLois Curfman McInnes 1507b4fd4287SBarry Smith Input Parameter: 1508b4fd4287SBarry Smith . snes - the nonlinear solver context 1509b4fd4287SBarry Smith 1510b4fd4287SBarry Smith Output Parameters: 1511c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 1512b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 151370e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 151470e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 1515fee21e36SBarry Smith 151636851e7fSLois Curfman McInnes Level: advanced 151736851e7fSLois Curfman McInnes 1518b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 1519b4fd4287SBarry Smith @*/ 15207087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 1521b4fd4287SBarry Smith { 15223a40ed3dSBarry Smith PetscFunctionBegin; 15230700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1524b4fd4287SBarry Smith if (A) *A = snes->jacobian; 1525b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 1526e7788613SBarry Smith if (func) *func = snes->ops->computejacobian; 152770e92668SMatthew Knepley if (ctx) *ctx = snes->jacP; 15283a40ed3dSBarry Smith PetscFunctionReturn(0); 1529b4fd4287SBarry Smith } 1530b4fd4287SBarry Smith 15319b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 15329b94acceSBarry Smith 15334a2ae208SSatish Balay #undef __FUNCT__ 15344a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 15359b94acceSBarry Smith /*@ 15369b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 1537272ac6f2SLois Curfman McInnes of a nonlinear solver. 15389b94acceSBarry Smith 1539fee21e36SBarry Smith Collective on SNES 1540fee21e36SBarry Smith 1541c7afd0dbSLois Curfman McInnes Input Parameters: 154270e92668SMatthew Knepley . snes - the SNES context 1543c7afd0dbSLois Curfman McInnes 1544272ac6f2SLois Curfman McInnes Notes: 1545272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 1546272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 1547272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 1548272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 1549272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 1550272ac6f2SLois Curfman McInnes 155136851e7fSLois Curfman McInnes Level: advanced 155236851e7fSLois Curfman McInnes 15539b94acceSBarry Smith .keywords: SNES, nonlinear, setup 15549b94acceSBarry Smith 15559b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 15569b94acceSBarry Smith @*/ 15577087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 15589b94acceSBarry Smith { 1559dfbe8321SBarry Smith PetscErrorCode ierr; 15603a40ed3dSBarry Smith 15613a40ed3dSBarry Smith PetscFunctionBegin; 15620700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15634dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 15649b94acceSBarry Smith 15657adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 156685385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 156785385478SLisandro Dalcin } 156885385478SLisandro Dalcin 1569efd51863SBarry Smith if (!snes->vec_func && snes->dm && !snes->vec_rhs) { 1570efd51863SBarry Smith ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 1571efd51863SBarry Smith } 157217186662SBarry Smith if (!snes->vec_func && !snes->vec_rhs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first"); 1573644e2e5bSBarry Smith if (!snes->ops->computefunction && !snes->vec_rhs && !snes->dm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() or SNESSetDM() first"); 157417186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 157558c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 157658c9b817SLisandro Dalcin 157758c9b817SLisandro Dalcin if (!snes->vec_func && snes->vec_rhs) { 157858c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_rhs, &snes->vec_func);CHKERRQ(ierr); 157958c9b817SLisandro Dalcin } 158058c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 158158c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 158258c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 158358c9b817SLisandro Dalcin } 158458c9b817SLisandro Dalcin 1585ef8dffc7SBarry Smith if (!snes->ops->computejacobian && snes->dm) { 1586ef8dffc7SBarry Smith Mat J; 1587ef8dffc7SBarry Smith ierr = DMGetMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr); 1588cab2e9ccSBarry Smith ierr = SNESSetJacobian(snes,J,J,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr); 1589cab2e9ccSBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 1590efd51863SBarry Smith } else if (snes->dm && !snes->jacobian_pre){ 1591efd51863SBarry Smith Mat J; 1592efd51863SBarry Smith ierr = DMGetMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr); 1593efd51863SBarry Smith ierr = SNESSetJacobian(snes,J,J,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1594efd51863SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 1595ef8dffc7SBarry Smith } 1596efd51863SBarry Smith 1597b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 1598b710008aSBarry Smith 1599d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 1600d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 1601d25893d9SBarry Smith } 1602d25893d9SBarry Smith 1603410397dcSLisandro Dalcin if (snes->ops->setup) { 1604410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 1605410397dcSLisandro Dalcin } 160658c9b817SLisandro Dalcin 16077aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 16083a40ed3dSBarry Smith PetscFunctionReturn(0); 16099b94acceSBarry Smith } 16109b94acceSBarry Smith 16114a2ae208SSatish Balay #undef __FUNCT__ 161237596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 161337596af1SLisandro Dalcin /*@ 161437596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 161537596af1SLisandro Dalcin 161637596af1SLisandro Dalcin Collective on SNES 161737596af1SLisandro Dalcin 161837596af1SLisandro Dalcin Input Parameter: 161937596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 162037596af1SLisandro Dalcin 1621d25893d9SBarry Smith Level: intermediate 1622d25893d9SBarry Smith 1623d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 162437596af1SLisandro Dalcin 162537596af1SLisandro Dalcin .keywords: SNES, destroy 162637596af1SLisandro Dalcin 162737596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 162837596af1SLisandro Dalcin @*/ 162937596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 163037596af1SLisandro Dalcin { 163137596af1SLisandro Dalcin PetscErrorCode ierr; 163237596af1SLisandro Dalcin 163337596af1SLisandro Dalcin PetscFunctionBegin; 163437596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1635d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 1636d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 1637d25893d9SBarry Smith snes->user = PETSC_NULL; 1638d25893d9SBarry Smith } 1639644e2e5bSBarry Smith if (snes->ops->computejacobian == SNESDefaultComputeJacobianColor && snes->dm) { 1640644e2e5bSBarry Smith ierr = MatFDColoringDestroy((MatFDColoring*)&snes->jacP);CHKERRQ(ierr); 1641644e2e5bSBarry Smith snes->ops->computejacobian = PETSC_NULL; 1642644e2e5bSBarry Smith } 1643d25893d9SBarry Smith 164437596af1SLisandro Dalcin if (snes->ops->reset) { 164537596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 164637596af1SLisandro Dalcin } 164737596af1SLisandro Dalcin if (snes->ksp) {ierr = KSPReset(snes->ksp);CHKERRQ(ierr);} 16486bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 16496bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 16506bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 16516bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 16526bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 16536bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 165437596af1SLisandro Dalcin if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);} 165537596af1SLisandro Dalcin if (snes->vwork) {ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);} 165637596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 165737596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 165837596af1SLisandro Dalcin PetscFunctionReturn(0); 165937596af1SLisandro Dalcin } 166037596af1SLisandro Dalcin 166137596af1SLisandro Dalcin #undef __FUNCT__ 16624a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 166352baeb72SSatish Balay /*@ 16649b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 16659b94acceSBarry Smith with SNESCreate(). 16669b94acceSBarry Smith 1667c7afd0dbSLois Curfman McInnes Collective on SNES 1668c7afd0dbSLois Curfman McInnes 16699b94acceSBarry Smith Input Parameter: 16709b94acceSBarry Smith . snes - the SNES context 16719b94acceSBarry Smith 167236851e7fSLois Curfman McInnes Level: beginner 167336851e7fSLois Curfman McInnes 16749b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 16759b94acceSBarry Smith 167663a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 16779b94acceSBarry Smith @*/ 16786bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 16799b94acceSBarry Smith { 16806849ba73SBarry Smith PetscErrorCode ierr; 16813a40ed3dSBarry Smith 16823a40ed3dSBarry Smith PetscFunctionBegin; 16836bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 16846bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 16856bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 1686d4bb536fSBarry Smith 16876bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 16886b8b9a38SLisandro Dalcin 1689be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 16906bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 16916bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 16926d4c513bSLisandro Dalcin 16936bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 16946bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 16956b8b9a38SLisandro Dalcin 16966bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 16976bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 16986bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 16996b8b9a38SLisandro Dalcin } 17006bf464f9SBarry Smith if ((*snes)->conv_malloc) { 17016bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 17026bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 170358c9b817SLisandro Dalcin } 17046bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 1705a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 17063a40ed3dSBarry Smith PetscFunctionReturn(0); 17079b94acceSBarry Smith } 17089b94acceSBarry Smith 17099b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 17109b94acceSBarry Smith 17114a2ae208SSatish Balay #undef __FUNCT__ 1712a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 1713a8054027SBarry Smith /*@ 1714a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 1715a8054027SBarry Smith 17163f9fe445SBarry Smith Logically Collective on SNES 1717a8054027SBarry Smith 1718a8054027SBarry Smith Input Parameters: 1719a8054027SBarry Smith + snes - the SNES context 1720a8054027SBarry 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 17213b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 1722a8054027SBarry Smith 1723a8054027SBarry Smith Options Database Keys: 1724a8054027SBarry Smith . -snes_lag_preconditioner <lag> 1725a8054027SBarry Smith 1726a8054027SBarry Smith Notes: 1727a8054027SBarry Smith The default is 1 1728a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1729a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 1730a8054027SBarry Smith 1731a8054027SBarry Smith Level: intermediate 1732a8054027SBarry Smith 1733a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 1734a8054027SBarry Smith 1735e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 1736a8054027SBarry Smith 1737a8054027SBarry Smith @*/ 17387087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 1739a8054027SBarry Smith { 1740a8054027SBarry Smith PetscFunctionBegin; 17410700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1742e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 1743e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 1744c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 1745a8054027SBarry Smith snes->lagpreconditioner = lag; 1746a8054027SBarry Smith PetscFunctionReturn(0); 1747a8054027SBarry Smith } 1748a8054027SBarry Smith 1749a8054027SBarry Smith #undef __FUNCT__ 1750efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 1751efd51863SBarry Smith /*@ 1752efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 1753efd51863SBarry Smith 1754efd51863SBarry Smith Logically Collective on SNES 1755efd51863SBarry Smith 1756efd51863SBarry Smith Input Parameters: 1757efd51863SBarry Smith + snes - the SNES context 1758efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 1759efd51863SBarry Smith 1760efd51863SBarry Smith Options Database Keys: 1761efd51863SBarry Smith . -snes_grid_sequence <steps> 1762efd51863SBarry Smith 1763efd51863SBarry Smith Level: intermediate 1764efd51863SBarry Smith 1765efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 1766efd51863SBarry Smith 1767efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 1768efd51863SBarry Smith 1769efd51863SBarry Smith @*/ 1770efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 1771efd51863SBarry Smith { 1772efd51863SBarry Smith PetscFunctionBegin; 1773efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1774efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 1775efd51863SBarry Smith snes->gridsequence = steps; 1776efd51863SBarry Smith PetscFunctionReturn(0); 1777efd51863SBarry Smith } 1778efd51863SBarry Smith 1779efd51863SBarry Smith #undef __FUNCT__ 1780a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 1781a8054027SBarry Smith /*@ 1782a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 1783a8054027SBarry Smith 17843f9fe445SBarry Smith Not Collective 1785a8054027SBarry Smith 1786a8054027SBarry Smith Input Parameter: 1787a8054027SBarry Smith . snes - the SNES context 1788a8054027SBarry Smith 1789a8054027SBarry Smith Output Parameter: 1790a8054027SBarry 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 17913b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 1792a8054027SBarry Smith 1793a8054027SBarry Smith Options Database Keys: 1794a8054027SBarry Smith . -snes_lag_preconditioner <lag> 1795a8054027SBarry Smith 1796a8054027SBarry Smith Notes: 1797a8054027SBarry Smith The default is 1 1798a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1799a8054027SBarry Smith 1800a8054027SBarry Smith Level: intermediate 1801a8054027SBarry Smith 1802a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 1803a8054027SBarry Smith 1804a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 1805a8054027SBarry Smith 1806a8054027SBarry Smith @*/ 18077087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 1808a8054027SBarry Smith { 1809a8054027SBarry Smith PetscFunctionBegin; 18100700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1811a8054027SBarry Smith *lag = snes->lagpreconditioner; 1812a8054027SBarry Smith PetscFunctionReturn(0); 1813a8054027SBarry Smith } 1814a8054027SBarry Smith 1815a8054027SBarry Smith #undef __FUNCT__ 1816e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 1817e35cf81dSBarry Smith /*@ 1818e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 1819e35cf81dSBarry Smith often the preconditioner is rebuilt. 1820e35cf81dSBarry Smith 18213f9fe445SBarry Smith Logically Collective on SNES 1822e35cf81dSBarry Smith 1823e35cf81dSBarry Smith Input Parameters: 1824e35cf81dSBarry Smith + snes - the SNES context 1825e35cf81dSBarry 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 1826fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 1827e35cf81dSBarry Smith 1828e35cf81dSBarry Smith Options Database Keys: 1829e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 1830e35cf81dSBarry Smith 1831e35cf81dSBarry Smith Notes: 1832e35cf81dSBarry Smith The default is 1 1833e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1834fe3ffe1eSBarry 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 1835fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 1836e35cf81dSBarry Smith 1837e35cf81dSBarry Smith Level: intermediate 1838e35cf81dSBarry Smith 1839e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 1840e35cf81dSBarry Smith 1841e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 1842e35cf81dSBarry Smith 1843e35cf81dSBarry Smith @*/ 18447087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 1845e35cf81dSBarry Smith { 1846e35cf81dSBarry Smith PetscFunctionBegin; 18470700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1848e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 1849e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 1850c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 1851e35cf81dSBarry Smith snes->lagjacobian = lag; 1852e35cf81dSBarry Smith PetscFunctionReturn(0); 1853e35cf81dSBarry Smith } 1854e35cf81dSBarry Smith 1855e35cf81dSBarry Smith #undef __FUNCT__ 1856e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 1857e35cf81dSBarry Smith /*@ 1858e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 1859e35cf81dSBarry Smith 18603f9fe445SBarry Smith Not Collective 1861e35cf81dSBarry Smith 1862e35cf81dSBarry Smith Input Parameter: 1863e35cf81dSBarry Smith . snes - the SNES context 1864e35cf81dSBarry Smith 1865e35cf81dSBarry Smith Output Parameter: 1866e35cf81dSBarry 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 1867e35cf81dSBarry Smith the Jacobian is built etc. 1868e35cf81dSBarry Smith 1869e35cf81dSBarry Smith Options Database Keys: 1870e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 1871e35cf81dSBarry Smith 1872e35cf81dSBarry Smith Notes: 1873e35cf81dSBarry Smith The default is 1 1874e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1875e35cf81dSBarry Smith 1876e35cf81dSBarry Smith Level: intermediate 1877e35cf81dSBarry Smith 1878e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 1879e35cf81dSBarry Smith 1880e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 1881e35cf81dSBarry Smith 1882e35cf81dSBarry Smith @*/ 18837087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 1884e35cf81dSBarry Smith { 1885e35cf81dSBarry Smith PetscFunctionBegin; 18860700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1887e35cf81dSBarry Smith *lag = snes->lagjacobian; 1888e35cf81dSBarry Smith PetscFunctionReturn(0); 1889e35cf81dSBarry Smith } 1890e35cf81dSBarry Smith 1891e35cf81dSBarry Smith #undef __FUNCT__ 18924a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 18939b94acceSBarry Smith /*@ 1894d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 18959b94acceSBarry Smith 18963f9fe445SBarry Smith Logically Collective on SNES 1897c7afd0dbSLois Curfman McInnes 18989b94acceSBarry Smith Input Parameters: 1899c7afd0dbSLois Curfman McInnes + snes - the SNES context 190070441072SBarry Smith . abstol - absolute convergence tolerance 190133174efeSLois Curfman McInnes . rtol - relative convergence tolerance 190233174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 190333174efeSLois Curfman McInnes of the change in the solution between steps 190433174efeSLois Curfman McInnes . maxit - maximum number of iterations 1905c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 1906fee21e36SBarry Smith 190733174efeSLois Curfman McInnes Options Database Keys: 190870441072SBarry Smith + -snes_atol <abstol> - Sets abstol 1909c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 1910c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 1911c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 1912c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 19139b94acceSBarry Smith 1914d7a720efSLois Curfman McInnes Notes: 19159b94acceSBarry Smith The default maximum number of iterations is 50. 19169b94acceSBarry Smith The default maximum number of function evaluations is 1000. 19179b94acceSBarry Smith 191836851e7fSLois Curfman McInnes Level: intermediate 191936851e7fSLois Curfman McInnes 192033174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 19219b94acceSBarry Smith 19222492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 19239b94acceSBarry Smith @*/ 19247087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 19259b94acceSBarry Smith { 19263a40ed3dSBarry Smith PetscFunctionBegin; 19270700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1928c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 1929c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 1930c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 1931c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 1932c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 1933c5eb9154SBarry Smith 193470441072SBarry Smith if (abstol != PETSC_DEFAULT) snes->abstol = abstol; 1935d7a720efSLois Curfman McInnes if (rtol != PETSC_DEFAULT) snes->rtol = rtol; 1936d7a720efSLois Curfman McInnes if (stol != PETSC_DEFAULT) snes->xtol = stol; 1937d7a720efSLois Curfman McInnes if (maxit != PETSC_DEFAULT) snes->max_its = maxit; 1938d7a720efSLois Curfman McInnes if (maxf != PETSC_DEFAULT) snes->max_funcs = maxf; 19393a40ed3dSBarry Smith PetscFunctionReturn(0); 19409b94acceSBarry Smith } 19419b94acceSBarry Smith 19424a2ae208SSatish Balay #undef __FUNCT__ 19434a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 19449b94acceSBarry Smith /*@ 194533174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 194633174efeSLois Curfman McInnes 1947c7afd0dbSLois Curfman McInnes Not Collective 1948c7afd0dbSLois Curfman McInnes 194933174efeSLois Curfman McInnes Input Parameters: 1950c7afd0dbSLois Curfman McInnes + snes - the SNES context 195185385478SLisandro Dalcin . atol - absolute convergence tolerance 195233174efeSLois Curfman McInnes . rtol - relative convergence tolerance 195333174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 195433174efeSLois Curfman McInnes of the change in the solution between steps 195533174efeSLois Curfman McInnes . maxit - maximum number of iterations 1956c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 1957fee21e36SBarry Smith 195833174efeSLois Curfman McInnes Notes: 195933174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 196033174efeSLois Curfman McInnes 196136851e7fSLois Curfman McInnes Level: intermediate 196236851e7fSLois Curfman McInnes 196333174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 196433174efeSLois Curfman McInnes 196533174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 196633174efeSLois Curfman McInnes @*/ 19677087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 196833174efeSLois Curfman McInnes { 19693a40ed3dSBarry Smith PetscFunctionBegin; 19700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 197185385478SLisandro Dalcin if (atol) *atol = snes->abstol; 197233174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 197333174efeSLois Curfman McInnes if (stol) *stol = snes->xtol; 197433174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 197533174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 19763a40ed3dSBarry Smith PetscFunctionReturn(0); 197733174efeSLois Curfman McInnes } 197833174efeSLois Curfman McInnes 19794a2ae208SSatish Balay #undef __FUNCT__ 19804a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 198133174efeSLois Curfman McInnes /*@ 19829b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 19839b94acceSBarry Smith 19843f9fe445SBarry Smith Logically Collective on SNES 1985fee21e36SBarry Smith 1986c7afd0dbSLois Curfman McInnes Input Parameters: 1987c7afd0dbSLois Curfman McInnes + snes - the SNES context 1988c7afd0dbSLois Curfman McInnes - tol - tolerance 1989c7afd0dbSLois Curfman McInnes 19909b94acceSBarry Smith Options Database Key: 1991c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 19929b94acceSBarry Smith 199336851e7fSLois Curfman McInnes Level: intermediate 199436851e7fSLois Curfman McInnes 19959b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 19969b94acceSBarry Smith 19972492ecdbSBarry Smith .seealso: SNESSetTolerances() 19989b94acceSBarry Smith @*/ 19997087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 20009b94acceSBarry Smith { 20013a40ed3dSBarry Smith PetscFunctionBegin; 20020700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2003c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 20049b94acceSBarry Smith snes->deltatol = tol; 20053a40ed3dSBarry Smith PetscFunctionReturn(0); 20069b94acceSBarry Smith } 20079b94acceSBarry Smith 2008df9fa365SBarry Smith /* 2009df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2010df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2011df9fa365SBarry Smith macros instead of functions 2012df9fa365SBarry Smith */ 20134a2ae208SSatish Balay #undef __FUNCT__ 2014a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 20157087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2016ce1608b8SBarry Smith { 2017dfbe8321SBarry Smith PetscErrorCode ierr; 2018ce1608b8SBarry Smith 2019ce1608b8SBarry Smith PetscFunctionBegin; 20200700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2021a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2022ce1608b8SBarry Smith PetscFunctionReturn(0); 2023ce1608b8SBarry Smith } 2024ce1608b8SBarry Smith 20254a2ae208SSatish Balay #undef __FUNCT__ 2026a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 20277087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2028df9fa365SBarry Smith { 2029dfbe8321SBarry Smith PetscErrorCode ierr; 2030df9fa365SBarry Smith 2031df9fa365SBarry Smith PetscFunctionBegin; 2032a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2033df9fa365SBarry Smith PetscFunctionReturn(0); 2034df9fa365SBarry Smith } 2035df9fa365SBarry Smith 20364a2ae208SSatish Balay #undef __FUNCT__ 2037a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 20386bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2039df9fa365SBarry Smith { 2040dfbe8321SBarry Smith PetscErrorCode ierr; 2041df9fa365SBarry Smith 2042df9fa365SBarry Smith PetscFunctionBegin; 2043a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2044df9fa365SBarry Smith PetscFunctionReturn(0); 2045df9fa365SBarry Smith } 2046df9fa365SBarry Smith 20477087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2048b271bb04SBarry Smith #undef __FUNCT__ 2049b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 20507087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2051b271bb04SBarry Smith { 2052b271bb04SBarry Smith PetscDrawLG lg; 2053b271bb04SBarry Smith PetscErrorCode ierr; 2054b271bb04SBarry Smith PetscReal x,y,per; 2055b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2056b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2057b271bb04SBarry Smith PetscDraw draw; 2058b271bb04SBarry Smith PetscFunctionBegin; 2059b271bb04SBarry Smith if (!monctx) { 2060b271bb04SBarry Smith MPI_Comm comm; 2061b271bb04SBarry Smith 2062b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2063b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2064b271bb04SBarry Smith } 2065b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2066b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2067b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2068b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2069b271bb04SBarry Smith x = (PetscReal) n; 2070b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2071b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2072b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2073b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2074b271bb04SBarry Smith } 2075b271bb04SBarry Smith 2076b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2077b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2078b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2079b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2080b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2081b271bb04SBarry Smith x = (PetscReal) n; 2082b271bb04SBarry Smith y = 100.0*per; 2083b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2084b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2085b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2086b271bb04SBarry Smith } 2087b271bb04SBarry Smith 2088b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2089b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2090b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2091b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2092b271bb04SBarry Smith x = (PetscReal) n; 2093b271bb04SBarry Smith y = (prev - rnorm)/prev; 2094b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2095b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2096b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2097b271bb04SBarry Smith } 2098b271bb04SBarry Smith 2099b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2100b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2101b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2102b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2103b271bb04SBarry Smith x = (PetscReal) n; 2104b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2105b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2106b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2107b271bb04SBarry Smith } 2108b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2109b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2110b271bb04SBarry Smith } 2111b271bb04SBarry Smith prev = rnorm; 2112b271bb04SBarry Smith PetscFunctionReturn(0); 2113b271bb04SBarry Smith } 2114b271bb04SBarry Smith 2115b271bb04SBarry Smith #undef __FUNCT__ 2116b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 21177087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2118b271bb04SBarry Smith { 2119b271bb04SBarry Smith PetscErrorCode ierr; 2120b271bb04SBarry Smith 2121b271bb04SBarry Smith PetscFunctionBegin; 2122b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2123b271bb04SBarry Smith PetscFunctionReturn(0); 2124b271bb04SBarry Smith } 2125b271bb04SBarry Smith 2126b271bb04SBarry Smith #undef __FUNCT__ 2127b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 21286bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2129b271bb04SBarry Smith { 2130b271bb04SBarry Smith PetscErrorCode ierr; 2131b271bb04SBarry Smith 2132b271bb04SBarry Smith PetscFunctionBegin; 2133b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2134b271bb04SBarry Smith PetscFunctionReturn(0); 2135b271bb04SBarry Smith } 2136b271bb04SBarry Smith 21377a03ce2fSLisandro Dalcin #undef __FUNCT__ 21387a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 21397a03ce2fSLisandro Dalcin /* 21407a03ce2fSLisandro Dalcin Runs the user provided monitor routines, if they exists. 21417a03ce2fSLisandro Dalcin */ 21427a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 21437a03ce2fSLisandro Dalcin { 21447a03ce2fSLisandro Dalcin PetscErrorCode ierr; 21457a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 21467a03ce2fSLisandro Dalcin 21477a03ce2fSLisandro Dalcin PetscFunctionBegin; 21487a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 21497a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 21507a03ce2fSLisandro Dalcin } 21517a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 21527a03ce2fSLisandro Dalcin } 21537a03ce2fSLisandro Dalcin 21549b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 21559b94acceSBarry Smith 21564a2ae208SSatish Balay #undef __FUNCT__ 2157a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 21589b94acceSBarry Smith /*@C 2159a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 21609b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 21619b94acceSBarry Smith progress. 21629b94acceSBarry Smith 21633f9fe445SBarry Smith Logically Collective on SNES 2164fee21e36SBarry Smith 2165c7afd0dbSLois Curfman McInnes Input Parameters: 2166c7afd0dbSLois Curfman McInnes + snes - the SNES context 2167c7afd0dbSLois Curfman McInnes . func - monitoring routine 2168b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 2169e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 2170b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 2171b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 21729b94acceSBarry Smith 2173c7afd0dbSLois Curfman McInnes Calling sequence of func: 2174a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2175c7afd0dbSLois Curfman McInnes 2176c7afd0dbSLois Curfman McInnes + snes - the SNES context 2177c7afd0dbSLois Curfman McInnes . its - iteration number 2178c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 217940a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 21809b94acceSBarry Smith 21819665c990SLois Curfman McInnes Options Database Keys: 2182a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 2183a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 2184a6570f20SBarry Smith uses SNESMonitorLGCreate() 2185cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 2186c7afd0dbSLois Curfman McInnes been hardwired into a code by 2187a6570f20SBarry Smith calls to SNESMonitorSet(), but 2188c7afd0dbSLois Curfman McInnes does not cancel those set via 2189c7afd0dbSLois Curfman McInnes the options database. 21909665c990SLois Curfman McInnes 2191639f9d9dSBarry Smith Notes: 21926bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 2193a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 21946bc08f3fSLois Curfman McInnes order in which they were set. 2195639f9d9dSBarry Smith 2196025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 2197025f1a04SBarry Smith 219836851e7fSLois Curfman McInnes Level: intermediate 219936851e7fSLois Curfman McInnes 22009b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 22019b94acceSBarry Smith 2202a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 22039b94acceSBarry Smith @*/ 2204c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 22059b94acceSBarry Smith { 2206b90d0a6eSBarry Smith PetscInt i; 2207649052a6SBarry Smith PetscErrorCode ierr; 2208b90d0a6eSBarry Smith 22093a40ed3dSBarry Smith PetscFunctionBegin; 22100700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 221117186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2212b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 2213649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 2214649052a6SBarry Smith if (monitordestroy) { 2215c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 2216649052a6SBarry Smith } 2217b90d0a6eSBarry Smith PetscFunctionReturn(0); 2218b90d0a6eSBarry Smith } 2219b90d0a6eSBarry Smith } 2220b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 2221b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 2222639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 22233a40ed3dSBarry Smith PetscFunctionReturn(0); 22249b94acceSBarry Smith } 22259b94acceSBarry Smith 22264a2ae208SSatish Balay #undef __FUNCT__ 2227a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 22285cd90555SBarry Smith /*@C 2229a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 22305cd90555SBarry Smith 22313f9fe445SBarry Smith Logically Collective on SNES 2232c7afd0dbSLois Curfman McInnes 22335cd90555SBarry Smith Input Parameters: 22345cd90555SBarry Smith . snes - the SNES context 22355cd90555SBarry Smith 22361a480d89SAdministrator Options Database Key: 2237a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 2238a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 2239c7afd0dbSLois Curfman McInnes set via the options database 22405cd90555SBarry Smith 22415cd90555SBarry Smith Notes: 22425cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 22435cd90555SBarry Smith 224436851e7fSLois Curfman McInnes Level: intermediate 224536851e7fSLois Curfman McInnes 22465cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 22475cd90555SBarry Smith 2248a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 22495cd90555SBarry Smith @*/ 22507087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 22515cd90555SBarry Smith { 2252d952e501SBarry Smith PetscErrorCode ierr; 2253d952e501SBarry Smith PetscInt i; 2254d952e501SBarry Smith 22555cd90555SBarry Smith PetscFunctionBegin; 22560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2257d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 2258d952e501SBarry Smith if (snes->monitordestroy[i]) { 22593c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 2260d952e501SBarry Smith } 2261d952e501SBarry Smith } 22625cd90555SBarry Smith snes->numbermonitors = 0; 22635cd90555SBarry Smith PetscFunctionReturn(0); 22645cd90555SBarry Smith } 22655cd90555SBarry Smith 22664a2ae208SSatish Balay #undef __FUNCT__ 22674a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 22689b94acceSBarry Smith /*@C 22699b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 22709b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 22719b94acceSBarry Smith 22723f9fe445SBarry Smith Logically Collective on SNES 2273fee21e36SBarry Smith 2274c7afd0dbSLois Curfman McInnes Input Parameters: 2275c7afd0dbSLois Curfman McInnes + snes - the SNES context 2276c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 22777f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 22787f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 22799b94acceSBarry Smith 2280c7afd0dbSLois Curfman McInnes Calling sequence of func: 228106ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 2282c7afd0dbSLois Curfman McInnes 2283c7afd0dbSLois Curfman McInnes + snes - the SNES context 228406ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 2285c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 2286184914b5SBarry Smith . reason - reason for convergence/divergence 2287c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 22884b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 22894b27c08aSLois Curfman McInnes - f - 2-norm of function 22909b94acceSBarry Smith 229136851e7fSLois Curfman McInnes Level: advanced 229236851e7fSLois Curfman McInnes 22939b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 22949b94acceSBarry Smith 229585385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 22969b94acceSBarry Smith @*/ 22977087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 22989b94acceSBarry Smith { 22997f7931b9SBarry Smith PetscErrorCode ierr; 23007f7931b9SBarry Smith 23013a40ed3dSBarry Smith PetscFunctionBegin; 23020700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 230385385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 23047f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 23057f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 23067f7931b9SBarry Smith } 230785385478SLisandro Dalcin snes->ops->converged = func; 23087f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 230985385478SLisandro Dalcin snes->cnvP = cctx; 23103a40ed3dSBarry Smith PetscFunctionReturn(0); 23119b94acceSBarry Smith } 23129b94acceSBarry Smith 23134a2ae208SSatish Balay #undef __FUNCT__ 23144a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 231552baeb72SSatish Balay /*@ 2316184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 2317184914b5SBarry Smith 2318184914b5SBarry Smith Not Collective 2319184914b5SBarry Smith 2320184914b5SBarry Smith Input Parameter: 2321184914b5SBarry Smith . snes - the SNES context 2322184914b5SBarry Smith 2323184914b5SBarry Smith Output Parameter: 23244d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 2325184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 2326184914b5SBarry Smith 2327184914b5SBarry Smith Level: intermediate 2328184914b5SBarry Smith 2329184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 2330184914b5SBarry Smith 2331184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 2332184914b5SBarry Smith 233385385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 2334184914b5SBarry Smith @*/ 23357087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 2336184914b5SBarry Smith { 2337184914b5SBarry Smith PetscFunctionBegin; 23380700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23394482741eSBarry Smith PetscValidPointer(reason,2); 2340184914b5SBarry Smith *reason = snes->reason; 2341184914b5SBarry Smith PetscFunctionReturn(0); 2342184914b5SBarry Smith } 2343184914b5SBarry Smith 23444a2ae208SSatish Balay #undef __FUNCT__ 23454a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 2346c9005455SLois Curfman McInnes /*@ 2347c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 2348c9005455SLois Curfman McInnes 23493f9fe445SBarry Smith Logically Collective on SNES 2350fee21e36SBarry Smith 2351c7afd0dbSLois Curfman McInnes Input Parameters: 2352c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 23538c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 2354cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 2355758f92a0SBarry Smith . na - size of a and its 235664731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 2357758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 2358c7afd0dbSLois Curfman McInnes 2359308dcc3eSBarry Smith Notes: 2360308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 2361308dcc3eSBarry Smith default array of length 10000 is allocated. 2362308dcc3eSBarry Smith 2363c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 2364c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 2365c9005455SLois Curfman McInnes during the section of code that is being timed. 2366c9005455SLois Curfman McInnes 236736851e7fSLois Curfman McInnes Level: intermediate 236836851e7fSLois Curfman McInnes 2369c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 2370758f92a0SBarry Smith 237108405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 2372758f92a0SBarry Smith 2373c9005455SLois Curfman McInnes @*/ 23747087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 2375c9005455SLois Curfman McInnes { 2376308dcc3eSBarry Smith PetscErrorCode ierr; 2377308dcc3eSBarry Smith 23783a40ed3dSBarry Smith PetscFunctionBegin; 23790700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23804482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 2381a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 2382308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 2383308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 2384308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 2385308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 2386308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 2387308dcc3eSBarry Smith } 2388c9005455SLois Curfman McInnes snes->conv_hist = a; 2389758f92a0SBarry Smith snes->conv_hist_its = its; 2390758f92a0SBarry Smith snes->conv_hist_max = na; 2391a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 2392758f92a0SBarry Smith snes->conv_hist_reset = reset; 2393758f92a0SBarry Smith PetscFunctionReturn(0); 2394758f92a0SBarry Smith } 2395758f92a0SBarry Smith 2396308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 2397c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 2398c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 2399308dcc3eSBarry Smith EXTERN_C_BEGIN 2400308dcc3eSBarry Smith #undef __FUNCT__ 2401308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 2402308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 2403308dcc3eSBarry Smith { 2404308dcc3eSBarry Smith mxArray *mat; 2405308dcc3eSBarry Smith PetscInt i; 2406308dcc3eSBarry Smith PetscReal *ar; 2407308dcc3eSBarry Smith 2408308dcc3eSBarry Smith PetscFunctionBegin; 2409308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 2410308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 2411308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 2412308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 2413308dcc3eSBarry Smith } 2414308dcc3eSBarry Smith PetscFunctionReturn(mat); 2415308dcc3eSBarry Smith } 2416308dcc3eSBarry Smith EXTERN_C_END 2417308dcc3eSBarry Smith #endif 2418308dcc3eSBarry Smith 2419308dcc3eSBarry Smith 24204a2ae208SSatish Balay #undef __FUNCT__ 24214a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 24220c4c9dddSBarry Smith /*@C 2423758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 2424758f92a0SBarry Smith 24253f9fe445SBarry Smith Not Collective 2426758f92a0SBarry Smith 2427758f92a0SBarry Smith Input Parameter: 2428758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 2429758f92a0SBarry Smith 2430758f92a0SBarry Smith Output Parameters: 2431758f92a0SBarry Smith . a - array to hold history 2432758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 2433758f92a0SBarry Smith negative if not converged) for each solve. 2434758f92a0SBarry Smith - na - size of a and its 2435758f92a0SBarry Smith 2436758f92a0SBarry Smith Notes: 2437758f92a0SBarry Smith The calling sequence for this routine in Fortran is 2438758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 2439758f92a0SBarry Smith 2440758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 2441758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 2442758f92a0SBarry Smith during the section of code that is being timed. 2443758f92a0SBarry Smith 2444758f92a0SBarry Smith Level: intermediate 2445758f92a0SBarry Smith 2446758f92a0SBarry Smith .keywords: SNES, get, convergence, history 2447758f92a0SBarry Smith 2448758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 2449758f92a0SBarry Smith 2450758f92a0SBarry Smith @*/ 24517087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 2452758f92a0SBarry Smith { 2453758f92a0SBarry Smith PetscFunctionBegin; 24540700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2455758f92a0SBarry Smith if (a) *a = snes->conv_hist; 2456758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 2457758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 24583a40ed3dSBarry Smith PetscFunctionReturn(0); 2459c9005455SLois Curfman McInnes } 2460c9005455SLois Curfman McInnes 2461e74ef692SMatthew Knepley #undef __FUNCT__ 2462e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 2463ac226902SBarry Smith /*@C 246476b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 2465eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 24667e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 246776b2cf59SMatthew Knepley 24683f9fe445SBarry Smith Logically Collective on SNES 246976b2cf59SMatthew Knepley 247076b2cf59SMatthew Knepley Input Parameters: 247176b2cf59SMatthew Knepley . snes - The nonlinear solver context 247276b2cf59SMatthew Knepley . func - The function 247376b2cf59SMatthew Knepley 247476b2cf59SMatthew Knepley Calling sequence of func: 2475b5d30489SBarry Smith . func (SNES snes, PetscInt step); 247676b2cf59SMatthew Knepley 247776b2cf59SMatthew Knepley . step - The current step of the iteration 247876b2cf59SMatthew Knepley 2479fe97e370SBarry Smith Level: advanced 2480fe97e370SBarry Smith 2481fe97e370SBarry 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() 2482fe97e370SBarry Smith This is not used by most users. 248376b2cf59SMatthew Knepley 248476b2cf59SMatthew Knepley .keywords: SNES, update 2485b5d30489SBarry Smith 248685385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 248776b2cf59SMatthew Knepley @*/ 24887087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 248976b2cf59SMatthew Knepley { 249076b2cf59SMatthew Knepley PetscFunctionBegin; 24910700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 2492e7788613SBarry Smith snes->ops->update = func; 249376b2cf59SMatthew Knepley PetscFunctionReturn(0); 249476b2cf59SMatthew Knepley } 249576b2cf59SMatthew Knepley 2496e74ef692SMatthew Knepley #undef __FUNCT__ 2497e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 249876b2cf59SMatthew Knepley /*@ 249976b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 250076b2cf59SMatthew Knepley 250176b2cf59SMatthew Knepley Not collective 250276b2cf59SMatthew Knepley 250376b2cf59SMatthew Knepley Input Parameters: 250476b2cf59SMatthew Knepley . snes - The nonlinear solver context 250576b2cf59SMatthew Knepley . step - The current step of the iteration 250676b2cf59SMatthew Knepley 2507205452f4SMatthew Knepley Level: intermediate 2508205452f4SMatthew Knepley 250976b2cf59SMatthew Knepley .keywords: SNES, update 2510a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 251176b2cf59SMatthew Knepley @*/ 25127087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 251376b2cf59SMatthew Knepley { 251476b2cf59SMatthew Knepley PetscFunctionBegin; 251576b2cf59SMatthew Knepley PetscFunctionReturn(0); 251676b2cf59SMatthew Knepley } 251776b2cf59SMatthew Knepley 25184a2ae208SSatish Balay #undef __FUNCT__ 25194a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 25209b94acceSBarry Smith /* 25219b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 25229b94acceSBarry Smith positive parameter delta. 25239b94acceSBarry Smith 25249b94acceSBarry Smith Input Parameters: 2525c7afd0dbSLois Curfman McInnes + snes - the SNES context 25269b94acceSBarry Smith . y - approximate solution of linear system 25279b94acceSBarry Smith . fnorm - 2-norm of current function 2528c7afd0dbSLois Curfman McInnes - delta - trust region size 25299b94acceSBarry Smith 25309b94acceSBarry Smith Output Parameters: 2531c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 25329b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 25339b94acceSBarry Smith region, and exceeds zero otherwise. 2534c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 25359b94acceSBarry Smith 25369b94acceSBarry Smith Note: 25374b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 25389b94acceSBarry Smith is set to be the maximum allowable step size. 25399b94acceSBarry Smith 25409b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 25419b94acceSBarry Smith */ 2542dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 25439b94acceSBarry Smith { 2544064f8208SBarry Smith PetscReal nrm; 2545ea709b57SSatish Balay PetscScalar cnorm; 2546dfbe8321SBarry Smith PetscErrorCode ierr; 25473a40ed3dSBarry Smith 25483a40ed3dSBarry Smith PetscFunctionBegin; 25490700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 25500700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 2551c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 2552184914b5SBarry Smith 2553064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 2554064f8208SBarry Smith if (nrm > *delta) { 2555064f8208SBarry Smith nrm = *delta/nrm; 2556064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 2557064f8208SBarry Smith cnorm = nrm; 25582dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 25599b94acceSBarry Smith *ynorm = *delta; 25609b94acceSBarry Smith } else { 25619b94acceSBarry Smith *gpnorm = 0.0; 2562064f8208SBarry Smith *ynorm = nrm; 25639b94acceSBarry Smith } 25643a40ed3dSBarry Smith PetscFunctionReturn(0); 25659b94acceSBarry Smith } 25669b94acceSBarry Smith 25674a2ae208SSatish Balay #undef __FUNCT__ 25684a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 25696ce558aeSBarry Smith /*@C 2570f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 2571f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 25729b94acceSBarry Smith 2573c7afd0dbSLois Curfman McInnes Collective on SNES 2574c7afd0dbSLois Curfman McInnes 2575b2002411SLois Curfman McInnes Input Parameters: 2576c7afd0dbSLois Curfman McInnes + snes - the SNES context 2577f69a0ea3SMatthew Knepley . b - the constant part of the equation, or PETSC_NULL to use zero. 257885385478SLisandro Dalcin - x - the solution vector. 25799b94acceSBarry Smith 2580b2002411SLois Curfman McInnes Notes: 25818ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 25828ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 25838ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 25848ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 25858ddd3da0SLois Curfman McInnes 258636851e7fSLois Curfman McInnes Level: beginner 258736851e7fSLois Curfman McInnes 25889b94acceSBarry Smith .keywords: SNES, nonlinear, solve 25899b94acceSBarry Smith 259085385478SLisandro Dalcin .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian() 25919b94acceSBarry Smith @*/ 25927087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 25939b94acceSBarry Smith { 2594dfbe8321SBarry Smith PetscErrorCode ierr; 2595ace3abfcSBarry Smith PetscBool flg; 2596eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 2597eabae89aSBarry Smith PetscViewer viewer; 2598efd51863SBarry Smith PetscInt grid; 2599052efed2SBarry Smith 26003a40ed3dSBarry Smith PetscFunctionBegin; 26010700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 26020700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,3); 2603f69a0ea3SMatthew Knepley PetscCheckSameComm(snes,1,x,3); 26040700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 260585385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 260685385478SLisandro Dalcin 2607efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 2608efd51863SBarry Smith 260985385478SLisandro Dalcin /* set solution vector */ 2610efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 26116bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 261285385478SLisandro Dalcin snes->vec_sol = x; 261385385478SLisandro Dalcin /* set afine vector if provided */ 261485385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 26156bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 261685385478SLisandro Dalcin snes->vec_rhs = b; 261785385478SLisandro Dalcin 261870e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 26193f149594SLisandro Dalcin 2620d25893d9SBarry Smith if (!grid && snes->ops->computeinitialguess) { 2621d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 2622d25893d9SBarry Smith } 2623d25893d9SBarry Smith 2624abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 262550ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 2626d5e45103SBarry Smith 26273f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 26284936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 262985385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 26304936397dSBarry Smith if (snes->domainerror){ 26314936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 26324936397dSBarry Smith snes->domainerror = PETSC_FALSE; 26334936397dSBarry Smith } 263417186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 26353f149594SLisandro Dalcin 26367adad957SLisandro Dalcin ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 2637eabae89aSBarry Smith if (flg && !PetscPreLoadingOn) { 26387adad957SLisandro Dalcin ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 2639eabae89aSBarry Smith ierr = SNESView(snes,viewer);CHKERRQ(ierr); 26406bf464f9SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 2641eabae89aSBarry Smith } 2642eabae89aSBarry Smith 264390d69ab7SBarry Smith flg = PETSC_FALSE; 2644acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 2645da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 26465968eb51SBarry Smith if (snes->printreason) { 26475968eb51SBarry Smith if (snes->reason > 0) { 26487adad957SLisandro Dalcin ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 26495968eb51SBarry Smith } else { 26507adad957SLisandro Dalcin ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 26515968eb51SBarry Smith } 26525968eb51SBarry Smith } 26535968eb51SBarry Smith 2654e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 2655efd51863SBarry Smith if (grid < snes->gridsequence) { 2656efd51863SBarry Smith DM fine; 2657efd51863SBarry Smith Vec xnew; 2658efd51863SBarry Smith Mat interp; 2659efd51863SBarry Smith 2660efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 2661efd51863SBarry Smith ierr = DMGetInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 2662efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 2663efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 2664efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 2665efd51863SBarry Smith x = xnew; 2666efd51863SBarry Smith 2667efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 2668efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 2669efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 2670efd51863SBarry Smith } 2671efd51863SBarry Smith } 26723a40ed3dSBarry Smith PetscFunctionReturn(0); 26739b94acceSBarry Smith } 26749b94acceSBarry Smith 26759b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 26769b94acceSBarry Smith 26774a2ae208SSatish Balay #undef __FUNCT__ 26784a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 267982bf6240SBarry Smith /*@C 26804b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 26819b94acceSBarry Smith 2682fee21e36SBarry Smith Collective on SNES 2683fee21e36SBarry Smith 2684c7afd0dbSLois Curfman McInnes Input Parameters: 2685c7afd0dbSLois Curfman McInnes + snes - the SNES context 2686454a90a3SBarry Smith - type - a known method 2687c7afd0dbSLois Curfman McInnes 2688c7afd0dbSLois Curfman McInnes Options Database Key: 2689454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 2690c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 2691ae12b187SLois Curfman McInnes 26929b94acceSBarry Smith Notes: 2693e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 26944b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 2695c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 26964b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 2697c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 26989b94acceSBarry Smith 2699ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 2700ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 2701ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 2702ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 2703ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 2704ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 2705ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 2706ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 2707ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 2708b0a32e0cSBarry Smith appropriate method. 270936851e7fSLois Curfman McInnes 271036851e7fSLois Curfman McInnes Level: intermediate 2711a703fe33SLois Curfman McInnes 2712454a90a3SBarry Smith .keywords: SNES, set, type 2713435da068SBarry Smith 2714435da068SBarry Smith .seealso: SNESType, SNESCreate() 2715435da068SBarry Smith 27169b94acceSBarry Smith @*/ 27177087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 27189b94acceSBarry Smith { 2719dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 2720ace3abfcSBarry Smith PetscBool match; 27213a40ed3dSBarry Smith 27223a40ed3dSBarry Smith PetscFunctionBegin; 27230700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 27244482741eSBarry Smith PetscValidCharPointer(type,2); 272582bf6240SBarry Smith 27266831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 27270f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 272892ff6ae8SBarry Smith 27294b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 2730e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 273175396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 273275396ef9SLisandro Dalcin if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); } 273375396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 273475396ef9SLisandro Dalcin snes->ops->setup = 0; 273575396ef9SLisandro Dalcin snes->ops->solve = 0; 273675396ef9SLisandro Dalcin snes->ops->view = 0; 273775396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 273875396ef9SLisandro Dalcin snes->ops->destroy = 0; 273975396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 274075396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 2741454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 274203bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 27439fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 27449fb22e1aSBarry Smith if (PetscAMSPublishAll) { 27459fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 27469fb22e1aSBarry Smith } 27479fb22e1aSBarry Smith #endif 27483a40ed3dSBarry Smith PetscFunctionReturn(0); 27499b94acceSBarry Smith } 27509b94acceSBarry Smith 2751a847f771SSatish Balay 27529b94acceSBarry Smith /* --------------------------------------------------------------------- */ 27534a2ae208SSatish Balay #undef __FUNCT__ 27544a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 275552baeb72SSatish Balay /*@ 27569b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 2757f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 27589b94acceSBarry Smith 2759fee21e36SBarry Smith Not Collective 2760fee21e36SBarry Smith 276136851e7fSLois Curfman McInnes Level: advanced 276236851e7fSLois Curfman McInnes 27639b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 27649b94acceSBarry Smith 27659b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 27669b94acceSBarry Smith @*/ 27677087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 27689b94acceSBarry Smith { 2769dfbe8321SBarry Smith PetscErrorCode ierr; 277082bf6240SBarry Smith 27713a40ed3dSBarry Smith PetscFunctionBegin; 27721441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 27734c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 27743a40ed3dSBarry Smith PetscFunctionReturn(0); 27759b94acceSBarry Smith } 27769b94acceSBarry Smith 27774a2ae208SSatish Balay #undef __FUNCT__ 27784a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 27799b94acceSBarry Smith /*@C 27809a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 27819b94acceSBarry Smith 2782c7afd0dbSLois Curfman McInnes Not Collective 2783c7afd0dbSLois Curfman McInnes 27849b94acceSBarry Smith Input Parameter: 27854b0e389bSBarry Smith . snes - nonlinear solver context 27869b94acceSBarry Smith 27879b94acceSBarry Smith Output Parameter: 27883a7fca6bSBarry Smith . type - SNES method (a character string) 27899b94acceSBarry Smith 279036851e7fSLois Curfman McInnes Level: intermediate 279136851e7fSLois Curfman McInnes 2792454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 27939b94acceSBarry Smith @*/ 27947087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 27959b94acceSBarry Smith { 27963a40ed3dSBarry Smith PetscFunctionBegin; 27970700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 27984482741eSBarry Smith PetscValidPointer(type,2); 27997adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 28003a40ed3dSBarry Smith PetscFunctionReturn(0); 28019b94acceSBarry Smith } 28029b94acceSBarry Smith 28034a2ae208SSatish Balay #undef __FUNCT__ 28044a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 280552baeb72SSatish Balay /*@ 28069b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 28079b94acceSBarry Smith stored. 28089b94acceSBarry Smith 2809c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 2810c7afd0dbSLois Curfman McInnes 28119b94acceSBarry Smith Input Parameter: 28129b94acceSBarry Smith . snes - the SNES context 28139b94acceSBarry Smith 28149b94acceSBarry Smith Output Parameter: 28159b94acceSBarry Smith . x - the solution 28169b94acceSBarry Smith 281770e92668SMatthew Knepley Level: intermediate 281836851e7fSLois Curfman McInnes 28199b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 28209b94acceSBarry Smith 282185385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 28229b94acceSBarry Smith @*/ 28237087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 28249b94acceSBarry Smith { 28253a40ed3dSBarry Smith PetscFunctionBegin; 28260700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 28274482741eSBarry Smith PetscValidPointer(x,2); 282885385478SLisandro Dalcin *x = snes->vec_sol; 282970e92668SMatthew Knepley PetscFunctionReturn(0); 283070e92668SMatthew Knepley } 283170e92668SMatthew Knepley 283270e92668SMatthew Knepley #undef __FUNCT__ 28334a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 283452baeb72SSatish Balay /*@ 28359b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 28369b94acceSBarry Smith stored. 28379b94acceSBarry Smith 2838c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 2839c7afd0dbSLois Curfman McInnes 28409b94acceSBarry Smith Input Parameter: 28419b94acceSBarry Smith . snes - the SNES context 28429b94acceSBarry Smith 28439b94acceSBarry Smith Output Parameter: 28449b94acceSBarry Smith . x - the solution update 28459b94acceSBarry Smith 284636851e7fSLois Curfman McInnes Level: advanced 284736851e7fSLois Curfman McInnes 28489b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 28499b94acceSBarry Smith 285085385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 28519b94acceSBarry Smith @*/ 28527087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 28539b94acceSBarry Smith { 28543a40ed3dSBarry Smith PetscFunctionBegin; 28550700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 28564482741eSBarry Smith PetscValidPointer(x,2); 285785385478SLisandro Dalcin *x = snes->vec_sol_update; 28583a40ed3dSBarry Smith PetscFunctionReturn(0); 28599b94acceSBarry Smith } 28609b94acceSBarry Smith 28614a2ae208SSatish Balay #undef __FUNCT__ 28624a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 28639b94acceSBarry Smith /*@C 28643638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 28659b94acceSBarry Smith 2866c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 2867c7afd0dbSLois Curfman McInnes 28689b94acceSBarry Smith Input Parameter: 28699b94acceSBarry Smith . snes - the SNES context 28709b94acceSBarry Smith 28719b94acceSBarry Smith Output Parameter: 28727bf4e008SBarry Smith + r - the function (or PETSC_NULL) 287370e92668SMatthew Knepley . func - the function (or PETSC_NULL) 287470e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 28759b94acceSBarry Smith 287636851e7fSLois Curfman McInnes Level: advanced 287736851e7fSLois Curfman McInnes 2878a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 28799b94acceSBarry Smith 28804b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 28819b94acceSBarry Smith @*/ 28827087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 28839b94acceSBarry Smith { 28843a40ed3dSBarry Smith PetscFunctionBegin; 28850700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 288685385478SLisandro Dalcin if (r) *r = snes->vec_func; 2887e7788613SBarry Smith if (func) *func = snes->ops->computefunction; 288870e92668SMatthew Knepley if (ctx) *ctx = snes->funP; 28893a40ed3dSBarry Smith PetscFunctionReturn(0); 28909b94acceSBarry Smith } 28919b94acceSBarry Smith 28924a2ae208SSatish Balay #undef __FUNCT__ 28934a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 28943c7409f5SSatish Balay /*@C 28953c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 2896d850072dSLois Curfman McInnes SNES options in the database. 28973c7409f5SSatish Balay 28983f9fe445SBarry Smith Logically Collective on SNES 2899fee21e36SBarry Smith 2900c7afd0dbSLois Curfman McInnes Input Parameter: 2901c7afd0dbSLois Curfman McInnes + snes - the SNES context 2902c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 2903c7afd0dbSLois Curfman McInnes 2904d850072dSLois Curfman McInnes Notes: 2905a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 2906c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 2907d850072dSLois Curfman McInnes 290836851e7fSLois Curfman McInnes Level: advanced 290936851e7fSLois Curfman McInnes 29103c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 2911a86d99e1SLois Curfman McInnes 2912a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 29133c7409f5SSatish Balay @*/ 29147087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 29153c7409f5SSatish Balay { 2916dfbe8321SBarry Smith PetscErrorCode ierr; 29173c7409f5SSatish Balay 29183a40ed3dSBarry Smith PetscFunctionBegin; 29190700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2920639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 29211cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 292294b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 29233a40ed3dSBarry Smith PetscFunctionReturn(0); 29243c7409f5SSatish Balay } 29253c7409f5SSatish Balay 29264a2ae208SSatish Balay #undef __FUNCT__ 29274a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 29283c7409f5SSatish Balay /*@C 2929f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 2930d850072dSLois Curfman McInnes SNES options in the database. 29313c7409f5SSatish Balay 29323f9fe445SBarry Smith Logically Collective on SNES 2933fee21e36SBarry Smith 2934c7afd0dbSLois Curfman McInnes Input Parameters: 2935c7afd0dbSLois Curfman McInnes + snes - the SNES context 2936c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 2937c7afd0dbSLois Curfman McInnes 2938d850072dSLois Curfman McInnes Notes: 2939a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 2940c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 2941d850072dSLois Curfman McInnes 294236851e7fSLois Curfman McInnes Level: advanced 294336851e7fSLois Curfman McInnes 29443c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 2945a86d99e1SLois Curfman McInnes 2946a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 29473c7409f5SSatish Balay @*/ 29487087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 29493c7409f5SSatish Balay { 2950dfbe8321SBarry Smith PetscErrorCode ierr; 29513c7409f5SSatish Balay 29523a40ed3dSBarry Smith PetscFunctionBegin; 29530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2954639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 29551cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 295694b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 29573a40ed3dSBarry Smith PetscFunctionReturn(0); 29583c7409f5SSatish Balay } 29593c7409f5SSatish Balay 29604a2ae208SSatish Balay #undef __FUNCT__ 29614a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 29629ab63eb5SSatish Balay /*@C 29633c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 29643c7409f5SSatish Balay SNES options in the database. 29653c7409f5SSatish Balay 2966c7afd0dbSLois Curfman McInnes Not Collective 2967c7afd0dbSLois Curfman McInnes 29683c7409f5SSatish Balay Input Parameter: 29693c7409f5SSatish Balay . snes - the SNES context 29703c7409f5SSatish Balay 29713c7409f5SSatish Balay Output Parameter: 29723c7409f5SSatish Balay . prefix - pointer to the prefix string used 29733c7409f5SSatish Balay 29744ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 29759ab63eb5SSatish Balay sufficient length to hold the prefix. 29769ab63eb5SSatish Balay 297736851e7fSLois Curfman McInnes Level: advanced 297836851e7fSLois Curfman McInnes 29793c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 2980a86d99e1SLois Curfman McInnes 2981a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 29823c7409f5SSatish Balay @*/ 29837087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 29843c7409f5SSatish Balay { 2985dfbe8321SBarry Smith PetscErrorCode ierr; 29863c7409f5SSatish Balay 29873a40ed3dSBarry Smith PetscFunctionBegin; 29880700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2989639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 29903a40ed3dSBarry Smith PetscFunctionReturn(0); 29913c7409f5SSatish Balay } 29923c7409f5SSatish Balay 2993b2002411SLois Curfman McInnes 29944a2ae208SSatish Balay #undef __FUNCT__ 29954a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 29963cea93caSBarry Smith /*@C 29973cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 29983cea93caSBarry Smith 29997f6c08e0SMatthew Knepley Level: advanced 30003cea93caSBarry Smith @*/ 30017087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3002b2002411SLois Curfman McInnes { 3003e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3004dfbe8321SBarry Smith PetscErrorCode ierr; 3005b2002411SLois Curfman McInnes 3006b2002411SLois Curfman McInnes PetscFunctionBegin; 3007b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3008c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3009b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3010b2002411SLois Curfman McInnes } 3011da9b6338SBarry Smith 3012da9b6338SBarry Smith #undef __FUNCT__ 3013da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 30147087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3015da9b6338SBarry Smith { 3016dfbe8321SBarry Smith PetscErrorCode ierr; 301777431f27SBarry Smith PetscInt N,i,j; 3018da9b6338SBarry Smith Vec u,uh,fh; 3019da9b6338SBarry Smith PetscScalar value; 3020da9b6338SBarry Smith PetscReal norm; 3021da9b6338SBarry Smith 3022da9b6338SBarry Smith PetscFunctionBegin; 3023da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3024da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3025da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3026da9b6338SBarry Smith 3027da9b6338SBarry Smith /* currently only works for sequential */ 3028da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3029da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3030da9b6338SBarry Smith for (i=0; i<N; i++) { 3031da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 303277431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3033da9b6338SBarry Smith for (j=-10; j<11; j++) { 3034ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3035da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 30363ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3037da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 303877431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3039da9b6338SBarry Smith value = -value; 3040da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3041da9b6338SBarry Smith } 3042da9b6338SBarry Smith } 30436bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 30446bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 3045da9b6338SBarry Smith PetscFunctionReturn(0); 3046da9b6338SBarry Smith } 304771f87433Sdalcinl 304871f87433Sdalcinl #undef __FUNCT__ 3049fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 305071f87433Sdalcinl /*@ 3051fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 305271f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 305371f87433Sdalcinl Newton method. 305471f87433Sdalcinl 30553f9fe445SBarry Smith Logically Collective on SNES 305671f87433Sdalcinl 305771f87433Sdalcinl Input Parameters: 305871f87433Sdalcinl + snes - SNES context 305971f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 306071f87433Sdalcinl 306164ba62caSBarry Smith Options Database: 306264ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 306364ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 306464ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 306564ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 306664ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 306764ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 306864ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 306964ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 307064ba62caSBarry Smith 307171f87433Sdalcinl Notes: 307271f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 307371f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 307471f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 307571f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 307671f87433Sdalcinl solver. 307771f87433Sdalcinl 307871f87433Sdalcinl Level: advanced 307971f87433Sdalcinl 308071f87433Sdalcinl Reference: 308171f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 308271f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 308371f87433Sdalcinl 308471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 308571f87433Sdalcinl 3086fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 308771f87433Sdalcinl @*/ 30887087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 308971f87433Sdalcinl { 309071f87433Sdalcinl PetscFunctionBegin; 30910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3092acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 309371f87433Sdalcinl snes->ksp_ewconv = flag; 309471f87433Sdalcinl PetscFunctionReturn(0); 309571f87433Sdalcinl } 309671f87433Sdalcinl 309771f87433Sdalcinl #undef __FUNCT__ 3098fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 309971f87433Sdalcinl /*@ 3100fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 310171f87433Sdalcinl for computing relative tolerance for linear solvers within an 310271f87433Sdalcinl inexact Newton method. 310371f87433Sdalcinl 310471f87433Sdalcinl Not Collective 310571f87433Sdalcinl 310671f87433Sdalcinl Input Parameter: 310771f87433Sdalcinl . snes - SNES context 310871f87433Sdalcinl 310971f87433Sdalcinl Output Parameter: 311071f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 311171f87433Sdalcinl 311271f87433Sdalcinl Notes: 311371f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 311471f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 311571f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 311671f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 311771f87433Sdalcinl solver. 311871f87433Sdalcinl 311971f87433Sdalcinl Level: advanced 312071f87433Sdalcinl 312171f87433Sdalcinl Reference: 312271f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 312371f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 312471f87433Sdalcinl 312571f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 312671f87433Sdalcinl 3127fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 312871f87433Sdalcinl @*/ 31297087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 313071f87433Sdalcinl { 313171f87433Sdalcinl PetscFunctionBegin; 31320700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 313371f87433Sdalcinl PetscValidPointer(flag,2); 313471f87433Sdalcinl *flag = snes->ksp_ewconv; 313571f87433Sdalcinl PetscFunctionReturn(0); 313671f87433Sdalcinl } 313771f87433Sdalcinl 313871f87433Sdalcinl #undef __FUNCT__ 3139fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 314071f87433Sdalcinl /*@ 3141fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 314271f87433Sdalcinl convergence criteria for the linear solvers within an inexact 314371f87433Sdalcinl Newton method. 314471f87433Sdalcinl 31453f9fe445SBarry Smith Logically Collective on SNES 314671f87433Sdalcinl 314771f87433Sdalcinl Input Parameters: 314871f87433Sdalcinl + snes - SNES context 314971f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 315071f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 315171f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 315271f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 315371f87433Sdalcinl (0 <= gamma2 <= 1) 315471f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 315571f87433Sdalcinl . alpha2 - power for safeguard 315671f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 315771f87433Sdalcinl 315871f87433Sdalcinl Note: 315971f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 316071f87433Sdalcinl 316171f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 316271f87433Sdalcinl 316371f87433Sdalcinl Level: advanced 316471f87433Sdalcinl 316571f87433Sdalcinl Reference: 316671f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 316771f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 316871f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 316971f87433Sdalcinl 317071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 317171f87433Sdalcinl 3172fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 317371f87433Sdalcinl @*/ 31747087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 317571f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 317671f87433Sdalcinl { 3177fa9f3622SBarry Smith SNESKSPEW *kctx; 317871f87433Sdalcinl PetscFunctionBegin; 31790700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3180fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3181e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 3182c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 3183c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 3184c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 3185c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 3186c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 3187c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 3188c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 318971f87433Sdalcinl 319071f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 319171f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 319271f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 319371f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 319471f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 319571f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 319671f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 319771f87433Sdalcinl 319871f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 3199e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 320071f87433Sdalcinl } 320171f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 3202e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 320371f87433Sdalcinl } 320471f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 3205e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 320671f87433Sdalcinl } 320771f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 3208e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 320971f87433Sdalcinl } 321071f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 3211e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 321271f87433Sdalcinl } 321371f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 3214e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 321571f87433Sdalcinl } 321671f87433Sdalcinl PetscFunctionReturn(0); 321771f87433Sdalcinl } 321871f87433Sdalcinl 321971f87433Sdalcinl #undef __FUNCT__ 3220fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 322171f87433Sdalcinl /*@ 3222fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 322371f87433Sdalcinl convergence criteria for the linear solvers within an inexact 322471f87433Sdalcinl Newton method. 322571f87433Sdalcinl 322671f87433Sdalcinl Not Collective 322771f87433Sdalcinl 322871f87433Sdalcinl Input Parameters: 322971f87433Sdalcinl snes - SNES context 323071f87433Sdalcinl 323171f87433Sdalcinl Output Parameters: 323271f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 323371f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 323471f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 323571f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 323671f87433Sdalcinl (0 <= gamma2 <= 1) 323771f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 323871f87433Sdalcinl . alpha2 - power for safeguard 323971f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 324071f87433Sdalcinl 324171f87433Sdalcinl Level: advanced 324271f87433Sdalcinl 324371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 324471f87433Sdalcinl 3245fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 324671f87433Sdalcinl @*/ 32477087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 324871f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 324971f87433Sdalcinl { 3250fa9f3622SBarry Smith SNESKSPEW *kctx; 325171f87433Sdalcinl PetscFunctionBegin; 32520700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3253fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3254e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 325571f87433Sdalcinl if(version) *version = kctx->version; 325671f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 325771f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 325871f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 325971f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 326071f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 326171f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 326271f87433Sdalcinl PetscFunctionReturn(0); 326371f87433Sdalcinl } 326471f87433Sdalcinl 326571f87433Sdalcinl #undef __FUNCT__ 3266fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 3267fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 326871f87433Sdalcinl { 326971f87433Sdalcinl PetscErrorCode ierr; 3270fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 327171f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 327271f87433Sdalcinl 327371f87433Sdalcinl PetscFunctionBegin; 3274e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 327571f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 327671f87433Sdalcinl rtol = kctx->rtol_0; 327771f87433Sdalcinl } else { 327871f87433Sdalcinl if (kctx->version == 1) { 327971f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 328071f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 328171f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 328271f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 328371f87433Sdalcinl } else if (kctx->version == 2) { 328471f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 328571f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 328671f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 328771f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 328871f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 328971f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 329071f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 329171f87433Sdalcinl stol = PetscMax(rtol,stol); 329271f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 329371f87433Sdalcinl /* safeguard: avoid oversolving */ 329471f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 329571f87433Sdalcinl stol = PetscMax(rtol,stol); 329671f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 3297e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 329871f87433Sdalcinl } 329971f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 330071f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 330171f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 330271f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 330371f87433Sdalcinl PetscFunctionReturn(0); 330471f87433Sdalcinl } 330571f87433Sdalcinl 330671f87433Sdalcinl #undef __FUNCT__ 3307fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 3308fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 330971f87433Sdalcinl { 331071f87433Sdalcinl PetscErrorCode ierr; 3311fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 331271f87433Sdalcinl PCSide pcside; 331371f87433Sdalcinl Vec lres; 331471f87433Sdalcinl 331571f87433Sdalcinl PetscFunctionBegin; 3316e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 331771f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 331871f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 331971f87433Sdalcinl if (kctx->version == 1) { 3320b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 332171f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 332271f87433Sdalcinl /* KSP residual is true linear residual */ 332371f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 332471f87433Sdalcinl } else { 332571f87433Sdalcinl /* KSP residual is preconditioned residual */ 332671f87433Sdalcinl /* compute true linear residual norm */ 332771f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 332871f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 332971f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 333071f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 33316bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 333271f87433Sdalcinl } 333371f87433Sdalcinl } 333471f87433Sdalcinl PetscFunctionReturn(0); 333571f87433Sdalcinl } 333671f87433Sdalcinl 333771f87433Sdalcinl #undef __FUNCT__ 333871f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 333971f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 334071f87433Sdalcinl { 334171f87433Sdalcinl PetscErrorCode ierr; 334271f87433Sdalcinl 334371f87433Sdalcinl PetscFunctionBegin; 3344fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 334571f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 3346fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 334771f87433Sdalcinl PetscFunctionReturn(0); 334871f87433Sdalcinl } 33496c699258SBarry Smith 33506c699258SBarry Smith #undef __FUNCT__ 33516c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 33526c699258SBarry Smith /*@ 33536c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 33546c699258SBarry Smith 33553f9fe445SBarry Smith Logically Collective on SNES 33566c699258SBarry Smith 33576c699258SBarry Smith Input Parameters: 33586c699258SBarry Smith + snes - the preconditioner context 33596c699258SBarry Smith - dm - the dm 33606c699258SBarry Smith 33616c699258SBarry Smith Level: intermediate 33626c699258SBarry Smith 33636c699258SBarry Smith 33646c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 33656c699258SBarry Smith @*/ 33667087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 33676c699258SBarry Smith { 33686c699258SBarry Smith PetscErrorCode ierr; 3369345fed2cSBarry Smith KSP ksp; 33706c699258SBarry Smith 33716c699258SBarry Smith PetscFunctionBegin; 33720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3373d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 33746bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 33756c699258SBarry Smith snes->dm = dm; 3376345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 3377345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 3378f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 33796c699258SBarry Smith PetscFunctionReturn(0); 33806c699258SBarry Smith } 33816c699258SBarry Smith 33826c699258SBarry Smith #undef __FUNCT__ 33836c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 33846c699258SBarry Smith /*@ 33856c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 33866c699258SBarry Smith 33873f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 33886c699258SBarry Smith 33896c699258SBarry Smith Input Parameter: 33906c699258SBarry Smith . snes - the preconditioner context 33916c699258SBarry Smith 33926c699258SBarry Smith Output Parameter: 33936c699258SBarry Smith . dm - the dm 33946c699258SBarry Smith 33956c699258SBarry Smith Level: intermediate 33966c699258SBarry Smith 33976c699258SBarry Smith 33986c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 33996c699258SBarry Smith @*/ 34007087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 34016c699258SBarry Smith { 34026c699258SBarry Smith PetscFunctionBegin; 34030700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34046c699258SBarry Smith *dm = snes->dm; 34056c699258SBarry Smith PetscFunctionReturn(0); 34066c699258SBarry Smith } 34070807856dSBarry Smith 340831823bd8SMatthew G Knepley #undef __FUNCT__ 340931823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 341031823bd8SMatthew G Knepley /*@ 341131823bd8SMatthew G Knepley SNESSetPC - Sets the preconditioner to be used. 341231823bd8SMatthew G Knepley 341331823bd8SMatthew G Knepley Collective on SNES 341431823bd8SMatthew G Knepley 341531823bd8SMatthew G Knepley Input Parameters: 341631823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 341731823bd8SMatthew G Knepley - pc - the preconditioner object 341831823bd8SMatthew G Knepley 341931823bd8SMatthew G Knepley Notes: 342031823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 342131823bd8SMatthew G Knepley to configure it using the API). 342231823bd8SMatthew G Knepley 342331823bd8SMatthew G Knepley Level: developer 342431823bd8SMatthew G Knepley 342531823bd8SMatthew G Knepley .keywords: SNES, set, precondition 342631823bd8SMatthew G Knepley .seealso: SNESGetPC() 342731823bd8SMatthew G Knepley @*/ 342831823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 342931823bd8SMatthew G Knepley { 343031823bd8SMatthew G Knepley PetscErrorCode ierr; 343131823bd8SMatthew G Knepley 343231823bd8SMatthew G Knepley PetscFunctionBegin; 343331823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 343431823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 343531823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 343631823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 3437bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 343831823bd8SMatthew G Knepley snes->pc = pc; 343931823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 344031823bd8SMatthew G Knepley PetscFunctionReturn(0); 344131823bd8SMatthew G Knepley } 344231823bd8SMatthew G Knepley 344331823bd8SMatthew G Knepley #undef __FUNCT__ 344431823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 344531823bd8SMatthew G Knepley /*@ 344631823bd8SMatthew G Knepley SNESGetPC - Returns a pointer to the preconditioner context set with SNESSetPC(). 344731823bd8SMatthew G Knepley 344831823bd8SMatthew G Knepley Not Collective 344931823bd8SMatthew G Knepley 345031823bd8SMatthew G Knepley Input Parameter: 345131823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 345231823bd8SMatthew G Knepley 345331823bd8SMatthew G Knepley Output Parameter: 345431823bd8SMatthew G Knepley . pc - preconditioner context 345531823bd8SMatthew G Knepley 345631823bd8SMatthew G Knepley Level: developer 345731823bd8SMatthew G Knepley 345831823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 345931823bd8SMatthew G Knepley .seealso: SNESSetPC() 346031823bd8SMatthew G Knepley @*/ 346131823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 346231823bd8SMatthew G Knepley { 346331823bd8SMatthew G Knepley PetscErrorCode ierr; 346431823bd8SMatthew G Knepley 346531823bd8SMatthew G Knepley PetscFunctionBegin; 346631823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 346731823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 346831823bd8SMatthew G Knepley if (!snes->pc) { 346931823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr); 3470*4a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr); 347131823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 347231823bd8SMatthew G Knepley } 347331823bd8SMatthew G Knepley *pc = snes->pc; 347431823bd8SMatthew G Knepley PetscFunctionReturn(0); 347531823bd8SMatthew G Knepley } 347631823bd8SMatthew G Knepley 347769b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3478c6db04a5SJed Brown #include <mex.h> 347969b4f73cSBarry Smith 34808f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 34818f6e6473SBarry Smith 34820807856dSBarry Smith #undef __FUNCT__ 34830807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 34840807856dSBarry Smith /* 34850807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 34860807856dSBarry Smith SNESSetFunctionMatlab(). 34870807856dSBarry Smith 34880807856dSBarry Smith Collective on SNES 34890807856dSBarry Smith 34900807856dSBarry Smith Input Parameters: 34910807856dSBarry Smith + snes - the SNES context 34920807856dSBarry Smith - x - input vector 34930807856dSBarry Smith 34940807856dSBarry Smith Output Parameter: 34950807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 34960807856dSBarry Smith 34970807856dSBarry Smith Notes: 34980807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 34990807856dSBarry Smith implementations, so most users would not generally call this routine 35000807856dSBarry Smith themselves. 35010807856dSBarry Smith 35020807856dSBarry Smith Level: developer 35030807856dSBarry Smith 35040807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 35050807856dSBarry Smith 35060807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 350761b2408cSBarry Smith */ 35087087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 35090807856dSBarry Smith { 3510e650e774SBarry Smith PetscErrorCode ierr; 35118f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 35128f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 35138f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 351491621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 3515e650e774SBarry Smith 35160807856dSBarry Smith PetscFunctionBegin; 35170807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35180807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 35190807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 35200807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 35210807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 35220807856dSBarry Smith 35230807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 3524e650e774SBarry Smith 352591621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3526e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3527e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 352891621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 352991621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 353091621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 35318f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 35328f6e6473SBarry Smith prhs[4] = sctx->ctx; 3533b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 3534e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3535e650e774SBarry Smith mxDestroyArray(prhs[0]); 3536e650e774SBarry Smith mxDestroyArray(prhs[1]); 3537e650e774SBarry Smith mxDestroyArray(prhs[2]); 35388f6e6473SBarry Smith mxDestroyArray(prhs[3]); 3539e650e774SBarry Smith mxDestroyArray(plhs[0]); 35400807856dSBarry Smith PetscFunctionReturn(0); 35410807856dSBarry Smith } 35420807856dSBarry Smith 35430807856dSBarry Smith 35440807856dSBarry Smith #undef __FUNCT__ 35450807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 354661b2408cSBarry Smith /* 35470807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 35480807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 3549e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 35500807856dSBarry Smith 35510807856dSBarry Smith Logically Collective on SNES 35520807856dSBarry Smith 35530807856dSBarry Smith Input Parameters: 35540807856dSBarry Smith + snes - the SNES context 35550807856dSBarry Smith . r - vector to store function value 35560807856dSBarry Smith - func - function evaluation routine 35570807856dSBarry Smith 35580807856dSBarry Smith Calling sequence of func: 355961b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 35600807856dSBarry Smith 35610807856dSBarry Smith 35620807856dSBarry Smith Notes: 35630807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 35640807856dSBarry Smith $ f'(x) x = -f(x), 35650807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 35660807856dSBarry Smith 35670807856dSBarry Smith Level: beginner 35680807856dSBarry Smith 35690807856dSBarry Smith .keywords: SNES, nonlinear, set, function 35700807856dSBarry Smith 35710807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 357261b2408cSBarry Smith */ 35737087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 35740807856dSBarry Smith { 35750807856dSBarry Smith PetscErrorCode ierr; 35768f6e6473SBarry Smith SNESMatlabContext *sctx; 35770807856dSBarry Smith 35780807856dSBarry Smith PetscFunctionBegin; 35798f6e6473SBarry Smith /* currently sctx is memory bleed */ 35808f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 35818f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 35828f6e6473SBarry Smith /* 35838f6e6473SBarry Smith This should work, but it doesn't 35848f6e6473SBarry Smith sctx->ctx = ctx; 35858f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 35868f6e6473SBarry Smith */ 35878f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 35888f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 35890807856dSBarry Smith PetscFunctionReturn(0); 35900807856dSBarry Smith } 359169b4f73cSBarry Smith 359261b2408cSBarry Smith #undef __FUNCT__ 359361b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 359461b2408cSBarry Smith /* 359561b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 359661b2408cSBarry Smith SNESSetJacobianMatlab(). 359761b2408cSBarry Smith 359861b2408cSBarry Smith Collective on SNES 359961b2408cSBarry Smith 360061b2408cSBarry Smith Input Parameters: 360161b2408cSBarry Smith + snes - the SNES context 360261b2408cSBarry Smith . x - input vector 360361b2408cSBarry Smith . A, B - the matrices 360461b2408cSBarry Smith - ctx - user context 360561b2408cSBarry Smith 360661b2408cSBarry Smith Output Parameter: 360761b2408cSBarry Smith . flag - structure of the matrix 360861b2408cSBarry Smith 360961b2408cSBarry Smith Level: developer 361061b2408cSBarry Smith 361161b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 361261b2408cSBarry Smith 361361b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 361461b2408cSBarry Smith @*/ 36157087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 361661b2408cSBarry Smith { 361761b2408cSBarry Smith PetscErrorCode ierr; 361861b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 361961b2408cSBarry Smith int nlhs = 2,nrhs = 6; 362061b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 362161b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 362261b2408cSBarry Smith 362361b2408cSBarry Smith PetscFunctionBegin; 362461b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 362561b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 362661b2408cSBarry Smith 362761b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 362861b2408cSBarry Smith 362961b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 363061b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 363161b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 363261b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 363361b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 363461b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 363561b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 363661b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 363761b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 363861b2408cSBarry Smith prhs[5] = sctx->ctx; 3639b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 364061b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 364161b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 364261b2408cSBarry Smith mxDestroyArray(prhs[0]); 364361b2408cSBarry Smith mxDestroyArray(prhs[1]); 364461b2408cSBarry Smith mxDestroyArray(prhs[2]); 364561b2408cSBarry Smith mxDestroyArray(prhs[3]); 364661b2408cSBarry Smith mxDestroyArray(prhs[4]); 364761b2408cSBarry Smith mxDestroyArray(plhs[0]); 364861b2408cSBarry Smith mxDestroyArray(plhs[1]); 364961b2408cSBarry Smith PetscFunctionReturn(0); 365061b2408cSBarry Smith } 365161b2408cSBarry Smith 365261b2408cSBarry Smith 365361b2408cSBarry Smith #undef __FUNCT__ 365461b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 365561b2408cSBarry Smith /* 365661b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 365761b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 3658e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 365961b2408cSBarry Smith 366061b2408cSBarry Smith Logically Collective on SNES 366161b2408cSBarry Smith 366261b2408cSBarry Smith Input Parameters: 366361b2408cSBarry Smith + snes - the SNES context 366461b2408cSBarry Smith . A,B - Jacobian matrices 366561b2408cSBarry Smith . func - function evaluation routine 366661b2408cSBarry Smith - ctx - user context 366761b2408cSBarry Smith 366861b2408cSBarry Smith Calling sequence of func: 366961b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 367061b2408cSBarry Smith 367161b2408cSBarry Smith 367261b2408cSBarry Smith Level: developer 367361b2408cSBarry Smith 367461b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 367561b2408cSBarry Smith 367661b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 367761b2408cSBarry Smith */ 36787087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 367961b2408cSBarry Smith { 368061b2408cSBarry Smith PetscErrorCode ierr; 368161b2408cSBarry Smith SNESMatlabContext *sctx; 368261b2408cSBarry Smith 368361b2408cSBarry Smith PetscFunctionBegin; 368461b2408cSBarry Smith /* currently sctx is memory bleed */ 368561b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 368661b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 368761b2408cSBarry Smith /* 368861b2408cSBarry Smith This should work, but it doesn't 368961b2408cSBarry Smith sctx->ctx = ctx; 369061b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 369161b2408cSBarry Smith */ 369261b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 369361b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 369461b2408cSBarry Smith PetscFunctionReturn(0); 369561b2408cSBarry Smith } 369669b4f73cSBarry Smith 3697f9eb7ae2SShri Abhyankar #undef __FUNCT__ 3698f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 3699f9eb7ae2SShri Abhyankar /* 3700f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 3701f9eb7ae2SShri Abhyankar 3702f9eb7ae2SShri Abhyankar Collective on SNES 3703f9eb7ae2SShri Abhyankar 3704f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 3705f9eb7ae2SShri Abhyankar @*/ 37067087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 3707f9eb7ae2SShri Abhyankar { 3708f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 370948f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3710f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 3711f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 3712f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 3713f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 3714f9eb7ae2SShri Abhyankar 3715f9eb7ae2SShri Abhyankar PetscFunctionBegin; 3716f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3717f9eb7ae2SShri Abhyankar 3718f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3719f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3720f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 3721f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 3722f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 3723f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 3724f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 3725f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 3726f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 3727f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3728f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 3729f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 3730f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 3731f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 3732f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 3733f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 3734f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 3735f9eb7ae2SShri Abhyankar } 3736f9eb7ae2SShri Abhyankar 3737f9eb7ae2SShri Abhyankar 3738f9eb7ae2SShri Abhyankar #undef __FUNCT__ 3739f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 3740f9eb7ae2SShri Abhyankar /* 3741e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 3742f9eb7ae2SShri Abhyankar 3743f9eb7ae2SShri Abhyankar Level: developer 3744f9eb7ae2SShri Abhyankar 3745f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 3746f9eb7ae2SShri Abhyankar 3747f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3748f9eb7ae2SShri Abhyankar */ 37497087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 3750f9eb7ae2SShri Abhyankar { 3751f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 3752f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 3753f9eb7ae2SShri Abhyankar 3754f9eb7ae2SShri Abhyankar PetscFunctionBegin; 3755f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 3756f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3757f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3758f9eb7ae2SShri Abhyankar /* 3759f9eb7ae2SShri Abhyankar This should work, but it doesn't 3760f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 3761f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 3762f9eb7ae2SShri Abhyankar */ 3763f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 3764f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 3765f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 3766f9eb7ae2SShri Abhyankar } 3767f9eb7ae2SShri Abhyankar 376869b4f73cSBarry Smith #endif 3769