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); 197b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 19894b7f48cSBarry Smith ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 199b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2003a40ed3dSBarry Smith PetscFunctionReturn(0); 2019b94acceSBarry Smith } 2029b94acceSBarry Smith 20376b2cf59SMatthew Knepley /* 20476b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 20576b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 20676b2cf59SMatthew Knepley */ 20776b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 208a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 2096849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 21076b2cf59SMatthew Knepley 211e74ef692SMatthew Knepley #undef __FUNCT__ 212e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker" 213ac226902SBarry Smith /*@C 21476b2cf59SMatthew Knepley SNESAddOptionsChecker - Adds an additional function to check for SNES options. 21576b2cf59SMatthew Knepley 21676b2cf59SMatthew Knepley Not Collective 21776b2cf59SMatthew Knepley 21876b2cf59SMatthew Knepley Input Parameter: 21976b2cf59SMatthew Knepley . snescheck - function that checks for options 22076b2cf59SMatthew Knepley 22176b2cf59SMatthew Knepley Level: developer 22276b2cf59SMatthew Knepley 22376b2cf59SMatthew Knepley .seealso: SNESSetFromOptions() 22476b2cf59SMatthew Knepley @*/ 2257087cfbeSBarry Smith PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 22676b2cf59SMatthew Knepley { 22776b2cf59SMatthew Knepley PetscFunctionBegin; 22876b2cf59SMatthew Knepley if (numberofsetfromoptions >= MAXSETFROMOPTIONS) { 229e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 23076b2cf59SMatthew Knepley } 23176b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 23276b2cf59SMatthew Knepley PetscFunctionReturn(0); 23376b2cf59SMatthew Knepley } 23476b2cf59SMatthew Knepley 2357087cfbeSBarry Smith extern PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 236aa3661deSLisandro Dalcin 237aa3661deSLisandro Dalcin #undef __FUNCT__ 238aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private" 239ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 240aa3661deSLisandro Dalcin { 241aa3661deSLisandro Dalcin Mat J; 242aa3661deSLisandro Dalcin KSP ksp; 243aa3661deSLisandro Dalcin PC pc; 244ace3abfcSBarry Smith PetscBool match; 245aa3661deSLisandro Dalcin PetscErrorCode ierr; 246aa3661deSLisandro Dalcin 247aa3661deSLisandro Dalcin PetscFunctionBegin; 2480700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 249aa3661deSLisandro Dalcin 25098613b67SLisandro Dalcin if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 25198613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 25298613b67SLisandro Dalcin ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr); 25398613b67SLisandro Dalcin } 25498613b67SLisandro Dalcin 255aa3661deSLisandro Dalcin if (version == 1) { 256aa3661deSLisandro Dalcin ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 25798613b67SLisandro Dalcin ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 2589c6ac3b3SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 259aa3661deSLisandro Dalcin } else if (version == 2) { 260e32f2f54SBarry Smith if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 261ce63c4c1SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL_LONG_DOUBLE) 262aa3661deSLisandro Dalcin ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr); 263aa3661deSLisandro Dalcin #else 264e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)"); 265aa3661deSLisandro Dalcin #endif 266a8248277SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2"); 267aa3661deSLisandro Dalcin 268aa3661deSLisandro Dalcin ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr); 269d3462f78SMatthew Knepley if (hasOperator) { 270aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 271aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 272aa3661deSLisandro Dalcin ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 273aa3661deSLisandro Dalcin } else { 274aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 275aa3661deSLisandro Dalcin provided preconditioner matrix with the default matrix free version. */ 276aa3661deSLisandro Dalcin ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);CHKERRQ(ierr); 277aa3661deSLisandro Dalcin /* Force no preconditioner */ 278aa3661deSLisandro Dalcin ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 279aa3661deSLisandro Dalcin ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 280aa3661deSLisandro Dalcin ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr); 281aa3661deSLisandro Dalcin if (!match) { 282aa3661deSLisandro Dalcin ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 283aa3661deSLisandro Dalcin ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 284aa3661deSLisandro Dalcin } 285aa3661deSLisandro Dalcin } 2866bf464f9SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 287aa3661deSLisandro Dalcin PetscFunctionReturn(0); 288aa3661deSLisandro Dalcin } 289aa3661deSLisandro Dalcin 2904a2ae208SSatish Balay #undef __FUNCT__ 2914a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions" 2929b94acceSBarry Smith /*@ 29394b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 2949b94acceSBarry Smith 295c7afd0dbSLois Curfman McInnes Collective on SNES 296c7afd0dbSLois Curfman McInnes 2979b94acceSBarry Smith Input Parameter: 2989b94acceSBarry Smith . snes - the SNES context 2999b94acceSBarry Smith 30036851e7fSLois Curfman McInnes Options Database Keys: 3016831982aSBarry Smith + -snes_type <type> - ls, tr, umls, umtr, test 30282738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 30382738288SBarry Smith of the change in the solution between steps 30470441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 305b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 306b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 307b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 30850ffb88aSMatthew Knepley . -snes_max_fail <max_fail> - maximum number of failures 309ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 310a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 311e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 312b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 3132492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 31482738288SBarry Smith solver; hence iterations will continue until max_it 3151fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 31682738288SBarry Smith of convergence test 317e8105e01SRichard Katz . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 318e8105e01SRichard Katz filename given prints to stdout 319a6570f20SBarry Smith . -snes_monitor_solution - plots solution at each iteration 320a6570f20SBarry Smith . -snes_monitor_residual - plots residual (not its norm) at each iteration 321a6570f20SBarry Smith . -snes_monitor_solution_update - plots update to solution at each iteration 322a6570f20SBarry Smith . -snes_monitor_draw - plots residual norm at each iteration 323e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 3245968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 325fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 32682738288SBarry Smith 32782738288SBarry Smith Options Database for Eisenstat-Walker method: 328fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 3294b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 33036851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 33136851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 33236851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 33336851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 33436851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 33536851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 33682738288SBarry Smith 33711ca99fdSLois Curfman McInnes Notes: 33811ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 3390598bfebSBarry Smith the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>. 34083e2fdc7SBarry Smith 34136851e7fSLois Curfman McInnes Level: beginner 34236851e7fSLois Curfman McInnes 3439b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 3449b94acceSBarry Smith 34569ed319cSSatish Balay .seealso: SNESSetOptionsPrefix() 3469b94acceSBarry Smith @*/ 3477087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 3489b94acceSBarry Smith { 349ace3abfcSBarry Smith PetscBool flg,mf,mf_operator; 350efd51863SBarry Smith PetscInt i,indx,lag,mf_version,grids; 351aa3661deSLisandro Dalcin MatStructure matflag; 35285385478SLisandro Dalcin const char *deft = SNESLS; 35385385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 35485385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 355e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 356649052a6SBarry Smith PetscViewer monviewer; 35785385478SLisandro Dalcin PetscErrorCode ierr; 3589b94acceSBarry Smith 3593a40ed3dSBarry Smith PetscFunctionBegin; 3600700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 361ca161407SBarry Smith 362186905e3SBarry Smith if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 363cce0b1b2SLisandro Dalcin ierr = PetscOptionsBegin(((PetscObject)snes)->comm,((PetscObject)snes)->prefix,"Nonlinear solver (SNES) options","SNES");CHKERRQ(ierr); 3647adad957SLisandro Dalcin if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; } 365b0a32e0cSBarry Smith ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 366d64ed03dSBarry Smith if (flg) { 367186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 3687adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 369186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 370d64ed03dSBarry Smith } 37190d69ab7SBarry Smith /* not used here, but called so will go into help messaage */ 372909c8a9fSBarry Smith ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 37393c39befSBarry Smith 37457034d6fSHong Zhang ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->xtol,&snes->xtol,0);CHKERRQ(ierr); 37557034d6fSHong Zhang ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 376186905e3SBarry Smith 37757034d6fSHong Zhang ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 378b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 379b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 38050ffb88aSMatthew Knepley ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 381ddf469c8SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr); 382acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr); 38385385478SLisandro Dalcin 384a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 385a8054027SBarry Smith if (flg) { 386a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 387a8054027SBarry Smith } 388e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 389e35cf81dSBarry Smith if (flg) { 390e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 391e35cf81dSBarry Smith } 392efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 393efd51863SBarry Smith if (flg) { 394efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 395efd51863SBarry Smith } 396a8054027SBarry Smith 39785385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 39885385478SLisandro Dalcin if (flg) { 39985385478SLisandro Dalcin switch (indx) { 4007f7931b9SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 4017f7931b9SBarry Smith case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 40285385478SLisandro Dalcin } 40385385478SLisandro Dalcin } 40485385478SLisandro Dalcin 405acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr); 406186905e3SBarry Smith 40785385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 40885385478SLisandro Dalcin 409acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 410186905e3SBarry Smith 411fa9f3622SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 412fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 413fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 414fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 415fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 416fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 417fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 418186905e3SBarry Smith 41990d69ab7SBarry Smith flg = PETSC_FALSE; 420acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 421a6570f20SBarry Smith if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 422eabae89aSBarry Smith 423a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 424e8105e01SRichard Katz if (flg) { 425649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 426649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 427e8105e01SRichard Katz } 428eabae89aSBarry Smith 429b271bb04SBarry Smith ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 430b271bb04SBarry Smith if (flg) { 431b271bb04SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 432b271bb04SBarry Smith } 433b271bb04SBarry Smith 434a6570f20SBarry Smith ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 435eabae89aSBarry Smith if (flg) { 436649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 437f1bef1bcSMatthew Knepley ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 438e8105e01SRichard Katz } 439eabae89aSBarry Smith 440a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 441eabae89aSBarry Smith if (flg) { 442649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 443649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 444eabae89aSBarry Smith } 445eabae89aSBarry Smith 44690d69ab7SBarry Smith flg = PETSC_FALSE; 447acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 448a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 44990d69ab7SBarry Smith flg = PETSC_FALSE; 450acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 451a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 45290d69ab7SBarry Smith flg = PETSC_FALSE; 453acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 454a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 45590d69ab7SBarry Smith flg = PETSC_FALSE; 456acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 457a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 45890d69ab7SBarry Smith flg = PETSC_FALSE; 459acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 460b271bb04SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 461e24b481bSBarry Smith 46290d69ab7SBarry Smith flg = PETSC_FALSE; 463acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 4644b27c08aSLois Curfman McInnes if (flg) { 465186905e3SBarry Smith ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);CHKERRQ(ierr); 466ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 4679b94acceSBarry Smith } 468639f9d9dSBarry Smith 469aa3661deSLisandro Dalcin mf = mf_operator = PETSC_FALSE; 470aa3661deSLisandro Dalcin flg = PETSC_FALSE; 471acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr); 472a8248277SBarry Smith if (flg && mf_operator) { 473a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 474a8248277SBarry Smith mf = PETSC_TRUE; 475a8248277SBarry Smith } 476aa3661deSLisandro Dalcin flg = PETSC_FALSE; 477acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr); 478aa3661deSLisandro Dalcin if (!flg && mf_operator) mf = PETSC_TRUE; 479aa3661deSLisandro Dalcin mf_version = 1; 480aa3661deSLisandro Dalcin ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr); 481aa3661deSLisandro Dalcin 48276b2cf59SMatthew Knepley for(i = 0; i < numberofsetfromoptions; i++) { 48376b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 48476b2cf59SMatthew Knepley } 48576b2cf59SMatthew Knepley 486e7788613SBarry Smith if (snes->ops->setfromoptions) { 487e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 488639f9d9dSBarry Smith } 4895d973c19SBarry Smith 4905d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 4915d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 492b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 4934bbc92c1SBarry Smith 494aa3661deSLisandro Dalcin if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 4951cee3971SBarry Smith 4961cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 497aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 498aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 49985385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 50093993e2dSLois Curfman McInnes 5013a40ed3dSBarry Smith PetscFunctionReturn(0); 5029b94acceSBarry Smith } 5039b94acceSBarry Smith 504d25893d9SBarry Smith #undef __FUNCT__ 505d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 506d25893d9SBarry Smith /*@ 507d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 508d25893d9SBarry Smith the nonlinear solvers. 509d25893d9SBarry Smith 510d25893d9SBarry Smith Logically Collective on SNES 511d25893d9SBarry Smith 512d25893d9SBarry Smith Input Parameters: 513d25893d9SBarry Smith + snes - the SNES context 514d25893d9SBarry Smith . compute - function to compute the context 515d25893d9SBarry Smith - destroy - function to destroy the context 516d25893d9SBarry Smith 517d25893d9SBarry Smith Level: intermediate 518d25893d9SBarry Smith 519d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 520d25893d9SBarry Smith 521d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 522d25893d9SBarry Smith @*/ 523d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 524d25893d9SBarry Smith { 525d25893d9SBarry Smith PetscFunctionBegin; 526d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 527d25893d9SBarry Smith snes->ops->usercompute = compute; 528d25893d9SBarry Smith snes->ops->userdestroy = destroy; 529d25893d9SBarry Smith PetscFunctionReturn(0); 530d25893d9SBarry Smith } 531a847f771SSatish Balay 5324a2ae208SSatish Balay #undef __FUNCT__ 5334a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 534b07ff414SBarry Smith /*@ 5359b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 5369b94acceSBarry Smith the nonlinear solvers. 5379b94acceSBarry Smith 5383f9fe445SBarry Smith Logically Collective on SNES 539fee21e36SBarry Smith 540c7afd0dbSLois Curfman McInnes Input Parameters: 541c7afd0dbSLois Curfman McInnes + snes - the SNES context 542c7afd0dbSLois Curfman McInnes - usrP - optional user context 543c7afd0dbSLois Curfman McInnes 54436851e7fSLois Curfman McInnes Level: intermediate 54536851e7fSLois Curfman McInnes 5469b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 5479b94acceSBarry Smith 548d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext() 5499b94acceSBarry Smith @*/ 5507087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 5519b94acceSBarry Smith { 5521b2093e4SBarry Smith PetscErrorCode ierr; 553b07ff414SBarry Smith KSP ksp; 5541b2093e4SBarry Smith 5553a40ed3dSBarry Smith PetscFunctionBegin; 5560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 557b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 558b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 5599b94acceSBarry Smith snes->user = usrP; 5603a40ed3dSBarry Smith PetscFunctionReturn(0); 5619b94acceSBarry Smith } 56274679c65SBarry Smith 5634a2ae208SSatish Balay #undef __FUNCT__ 5644a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 565b07ff414SBarry Smith /*@ 5669b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 5679b94acceSBarry Smith nonlinear solvers. 5689b94acceSBarry Smith 569c7afd0dbSLois Curfman McInnes Not Collective 570c7afd0dbSLois Curfman McInnes 5719b94acceSBarry Smith Input Parameter: 5729b94acceSBarry Smith . snes - SNES context 5739b94acceSBarry Smith 5749b94acceSBarry Smith Output Parameter: 5759b94acceSBarry Smith . usrP - user context 5769b94acceSBarry Smith 57736851e7fSLois Curfman McInnes Level: intermediate 57836851e7fSLois Curfman McInnes 5799b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 5809b94acceSBarry Smith 5819b94acceSBarry Smith .seealso: SNESSetApplicationContext() 5829b94acceSBarry Smith @*/ 5837087cfbeSBarry Smith PetscErrorCode SNESGetApplicationContext(SNES snes,void **usrP) 5849b94acceSBarry Smith { 5853a40ed3dSBarry Smith PetscFunctionBegin; 5860700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5879b94acceSBarry Smith *usrP = snes->user; 5883a40ed3dSBarry Smith PetscFunctionReturn(0); 5899b94acceSBarry Smith } 59074679c65SBarry Smith 5914a2ae208SSatish Balay #undef __FUNCT__ 5924a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 5939b94acceSBarry Smith /*@ 594c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 595c8228a4eSBarry Smith at this time. 5969b94acceSBarry Smith 597c7afd0dbSLois Curfman McInnes Not Collective 598c7afd0dbSLois Curfman McInnes 5999b94acceSBarry Smith Input Parameter: 6009b94acceSBarry Smith . snes - SNES context 6019b94acceSBarry Smith 6029b94acceSBarry Smith Output Parameter: 6039b94acceSBarry Smith . iter - iteration number 6049b94acceSBarry Smith 605c8228a4eSBarry Smith Notes: 606c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 607c8228a4eSBarry Smith 608c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 60908405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 61008405cd6SLois Curfman McInnes .vb 61108405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 61208405cd6SLois Curfman McInnes if (!(it % 2)) { 61308405cd6SLois Curfman McInnes [compute Jacobian here] 61408405cd6SLois Curfman McInnes } 61508405cd6SLois Curfman McInnes .ve 616c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 61708405cd6SLois Curfman McInnes recomputed every second SNES iteration. 618c8228a4eSBarry Smith 61936851e7fSLois Curfman McInnes Level: intermediate 62036851e7fSLois Curfman McInnes 6212b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 6222b668275SBarry Smith 623b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 6249b94acceSBarry Smith @*/ 6257087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 6269b94acceSBarry Smith { 6273a40ed3dSBarry Smith PetscFunctionBegin; 6280700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 6294482741eSBarry Smith PetscValidIntPointer(iter,2); 6309b94acceSBarry Smith *iter = snes->iter; 6313a40ed3dSBarry Smith PetscFunctionReturn(0); 6329b94acceSBarry Smith } 63374679c65SBarry Smith 6344a2ae208SSatish Balay #undef __FUNCT__ 6354a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 6369b94acceSBarry Smith /*@ 6379b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 6389b94acceSBarry Smith with SNESSSetFunction(). 6399b94acceSBarry Smith 640c7afd0dbSLois Curfman McInnes Collective on SNES 641c7afd0dbSLois Curfman McInnes 6429b94acceSBarry Smith Input Parameter: 6439b94acceSBarry Smith . snes - SNES context 6449b94acceSBarry Smith 6459b94acceSBarry Smith Output Parameter: 6469b94acceSBarry Smith . fnorm - 2-norm of function 6479b94acceSBarry Smith 64836851e7fSLois Curfman McInnes Level: intermediate 64936851e7fSLois Curfman McInnes 6509b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 651a86d99e1SLois Curfman McInnes 652b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 6539b94acceSBarry Smith @*/ 6547087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 6559b94acceSBarry Smith { 6563a40ed3dSBarry Smith PetscFunctionBegin; 6570700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 6584482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 6599b94acceSBarry Smith *fnorm = snes->norm; 6603a40ed3dSBarry Smith PetscFunctionReturn(0); 6619b94acceSBarry Smith } 66274679c65SBarry Smith 6634a2ae208SSatish Balay #undef __FUNCT__ 664b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 6659b94acceSBarry Smith /*@ 666b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 6679b94acceSBarry Smith attempted by the nonlinear solver. 6689b94acceSBarry Smith 669c7afd0dbSLois Curfman McInnes Not Collective 670c7afd0dbSLois Curfman McInnes 6719b94acceSBarry Smith Input Parameter: 6729b94acceSBarry Smith . snes - SNES context 6739b94acceSBarry Smith 6749b94acceSBarry Smith Output Parameter: 6759b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 6769b94acceSBarry Smith 677c96a6f78SLois Curfman McInnes Notes: 678c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 679c96a6f78SLois Curfman McInnes 68036851e7fSLois Curfman McInnes Level: intermediate 68136851e7fSLois Curfman McInnes 6829b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 68358ebbce7SBarry Smith 684e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 68558ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 6869b94acceSBarry Smith @*/ 6877087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 6889b94acceSBarry Smith { 6893a40ed3dSBarry Smith PetscFunctionBegin; 6900700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 6914482741eSBarry Smith PetscValidIntPointer(nfails,2); 69250ffb88aSMatthew Knepley *nfails = snes->numFailures; 69350ffb88aSMatthew Knepley PetscFunctionReturn(0); 69450ffb88aSMatthew Knepley } 69550ffb88aSMatthew Knepley 69650ffb88aSMatthew Knepley #undef __FUNCT__ 697b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 69850ffb88aSMatthew Knepley /*@ 699b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 70050ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 70150ffb88aSMatthew Knepley 70250ffb88aSMatthew Knepley Not Collective 70350ffb88aSMatthew Knepley 70450ffb88aSMatthew Knepley Input Parameters: 70550ffb88aSMatthew Knepley + snes - SNES context 70650ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 70750ffb88aSMatthew Knepley 70850ffb88aSMatthew Knepley Level: intermediate 70950ffb88aSMatthew Knepley 71050ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 71158ebbce7SBarry Smith 712e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 71358ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 71450ffb88aSMatthew Knepley @*/ 7157087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 71650ffb88aSMatthew Knepley { 71750ffb88aSMatthew Knepley PetscFunctionBegin; 7180700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 71950ffb88aSMatthew Knepley snes->maxFailures = maxFails; 72050ffb88aSMatthew Knepley PetscFunctionReturn(0); 72150ffb88aSMatthew Knepley } 72250ffb88aSMatthew Knepley 72350ffb88aSMatthew Knepley #undef __FUNCT__ 724b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 72550ffb88aSMatthew Knepley /*@ 726b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 72750ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 72850ffb88aSMatthew Knepley 72950ffb88aSMatthew Knepley Not Collective 73050ffb88aSMatthew Knepley 73150ffb88aSMatthew Knepley Input Parameter: 73250ffb88aSMatthew Knepley . snes - SNES context 73350ffb88aSMatthew Knepley 73450ffb88aSMatthew Knepley Output Parameter: 73550ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 73650ffb88aSMatthew Knepley 73750ffb88aSMatthew Knepley Level: intermediate 73850ffb88aSMatthew Knepley 73950ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 74058ebbce7SBarry Smith 741e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 74258ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 74358ebbce7SBarry Smith 74450ffb88aSMatthew Knepley @*/ 7457087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 74650ffb88aSMatthew Knepley { 74750ffb88aSMatthew Knepley PetscFunctionBegin; 7480700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7494482741eSBarry Smith PetscValidIntPointer(maxFails,2); 75050ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 7513a40ed3dSBarry Smith PetscFunctionReturn(0); 7529b94acceSBarry Smith } 753a847f771SSatish Balay 7544a2ae208SSatish Balay #undef __FUNCT__ 7552541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 7562541af92SBarry Smith /*@ 7572541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 7582541af92SBarry Smith done by SNES. 7592541af92SBarry Smith 7602541af92SBarry Smith Not Collective 7612541af92SBarry Smith 7622541af92SBarry Smith Input Parameter: 7632541af92SBarry Smith . snes - SNES context 7642541af92SBarry Smith 7652541af92SBarry Smith Output Parameter: 7662541af92SBarry Smith . nfuncs - number of evaluations 7672541af92SBarry Smith 7682541af92SBarry Smith Level: intermediate 7692541af92SBarry Smith 7702541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 77158ebbce7SBarry Smith 772e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 7732541af92SBarry Smith @*/ 7747087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 7752541af92SBarry Smith { 7762541af92SBarry Smith PetscFunctionBegin; 7770700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7782541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 7792541af92SBarry Smith *nfuncs = snes->nfuncs; 7802541af92SBarry Smith PetscFunctionReturn(0); 7812541af92SBarry Smith } 7822541af92SBarry Smith 7832541af92SBarry Smith #undef __FUNCT__ 7843d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 7853d4c4710SBarry Smith /*@ 7863d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 7873d4c4710SBarry Smith linear solvers. 7883d4c4710SBarry Smith 7893d4c4710SBarry Smith Not Collective 7903d4c4710SBarry Smith 7913d4c4710SBarry Smith Input Parameter: 7923d4c4710SBarry Smith . snes - SNES context 7933d4c4710SBarry Smith 7943d4c4710SBarry Smith Output Parameter: 7953d4c4710SBarry Smith . nfails - number of failed solves 7963d4c4710SBarry Smith 7973d4c4710SBarry Smith Notes: 7983d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 7993d4c4710SBarry Smith 8003d4c4710SBarry Smith Level: intermediate 8013d4c4710SBarry Smith 8023d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 80358ebbce7SBarry Smith 804e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 8053d4c4710SBarry Smith @*/ 8067087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 8073d4c4710SBarry Smith { 8083d4c4710SBarry Smith PetscFunctionBegin; 8090700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8103d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 8113d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 8123d4c4710SBarry Smith PetscFunctionReturn(0); 8133d4c4710SBarry Smith } 8143d4c4710SBarry Smith 8153d4c4710SBarry Smith #undef __FUNCT__ 8163d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 8173d4c4710SBarry Smith /*@ 8183d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 8193d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 8203d4c4710SBarry Smith 8213f9fe445SBarry Smith Logically Collective on SNES 8223d4c4710SBarry Smith 8233d4c4710SBarry Smith Input Parameters: 8243d4c4710SBarry Smith + snes - SNES context 8253d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 8263d4c4710SBarry Smith 8273d4c4710SBarry Smith Level: intermediate 8283d4c4710SBarry Smith 829a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 8303d4c4710SBarry Smith 8313d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 8323d4c4710SBarry Smith 83358ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 8343d4c4710SBarry Smith @*/ 8357087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 8363d4c4710SBarry Smith { 8373d4c4710SBarry Smith PetscFunctionBegin; 8380700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 839c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 8403d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 8413d4c4710SBarry Smith PetscFunctionReturn(0); 8423d4c4710SBarry Smith } 8433d4c4710SBarry Smith 8443d4c4710SBarry Smith #undef __FUNCT__ 8453d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 8463d4c4710SBarry Smith /*@ 8473d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 8483d4c4710SBarry Smith are allowed before SNES terminates 8493d4c4710SBarry Smith 8503d4c4710SBarry Smith Not Collective 8513d4c4710SBarry Smith 8523d4c4710SBarry Smith Input Parameter: 8533d4c4710SBarry Smith . snes - SNES context 8543d4c4710SBarry Smith 8553d4c4710SBarry Smith Output Parameter: 8563d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 8573d4c4710SBarry Smith 8583d4c4710SBarry Smith Level: intermediate 8593d4c4710SBarry Smith 8603d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 8613d4c4710SBarry Smith 8623d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 8633d4c4710SBarry Smith 864e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 8653d4c4710SBarry Smith @*/ 8667087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 8673d4c4710SBarry Smith { 8683d4c4710SBarry Smith PetscFunctionBegin; 8690700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8703d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 8713d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 8723d4c4710SBarry Smith PetscFunctionReturn(0); 8733d4c4710SBarry Smith } 8743d4c4710SBarry Smith 8753d4c4710SBarry Smith #undef __FUNCT__ 876b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 877c96a6f78SLois Curfman McInnes /*@ 878b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 879c96a6f78SLois Curfman McInnes used by the nonlinear solver. 880c96a6f78SLois Curfman McInnes 881c7afd0dbSLois Curfman McInnes Not Collective 882c7afd0dbSLois Curfman McInnes 883c96a6f78SLois Curfman McInnes Input Parameter: 884c96a6f78SLois Curfman McInnes . snes - SNES context 885c96a6f78SLois Curfman McInnes 886c96a6f78SLois Curfman McInnes Output Parameter: 887c96a6f78SLois Curfman McInnes . lits - number of linear iterations 888c96a6f78SLois Curfman McInnes 889c96a6f78SLois Curfman McInnes Notes: 890c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 891c96a6f78SLois Curfman McInnes 89236851e7fSLois Curfman McInnes Level: intermediate 89336851e7fSLois Curfman McInnes 894c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 8952b668275SBarry Smith 8968c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 897c96a6f78SLois Curfman McInnes @*/ 8987087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 899c96a6f78SLois Curfman McInnes { 9003a40ed3dSBarry Smith PetscFunctionBegin; 9010700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9024482741eSBarry Smith PetscValidIntPointer(lits,2); 903c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 9043a40ed3dSBarry Smith PetscFunctionReturn(0); 905c96a6f78SLois Curfman McInnes } 906c96a6f78SLois Curfman McInnes 9074a2ae208SSatish Balay #undef __FUNCT__ 90894b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 90952baeb72SSatish Balay /*@ 91094b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 9119b94acceSBarry Smith 91294b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 913c7afd0dbSLois Curfman McInnes 9149b94acceSBarry Smith Input Parameter: 9159b94acceSBarry Smith . snes - the SNES context 9169b94acceSBarry Smith 9179b94acceSBarry Smith Output Parameter: 91894b7f48cSBarry Smith . ksp - the KSP context 9199b94acceSBarry Smith 9209b94acceSBarry Smith Notes: 92194b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 9229b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 9232999313aSBarry Smith PC contexts as well. 9249b94acceSBarry Smith 92536851e7fSLois Curfman McInnes Level: beginner 92636851e7fSLois Curfman McInnes 92794b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 9289b94acceSBarry Smith 9292999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 9309b94acceSBarry Smith @*/ 9317087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 9329b94acceSBarry Smith { 9331cee3971SBarry Smith PetscErrorCode ierr; 9341cee3971SBarry Smith 9353a40ed3dSBarry Smith PetscFunctionBegin; 9360700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9374482741eSBarry Smith PetscValidPointer(ksp,2); 9381cee3971SBarry Smith 9391cee3971SBarry Smith if (!snes->ksp) { 9401cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 9411cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 9421cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 9431cee3971SBarry Smith } 94494b7f48cSBarry Smith *ksp = snes->ksp; 9453a40ed3dSBarry Smith PetscFunctionReturn(0); 9469b94acceSBarry Smith } 94782bf6240SBarry Smith 9484a2ae208SSatish Balay #undef __FUNCT__ 9492999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 9502999313aSBarry Smith /*@ 9512999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 9522999313aSBarry Smith 9532999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 9542999313aSBarry Smith 9552999313aSBarry Smith Input Parameters: 9562999313aSBarry Smith + snes - the SNES context 9572999313aSBarry Smith - ksp - the KSP context 9582999313aSBarry Smith 9592999313aSBarry Smith Notes: 9602999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 9612999313aSBarry Smith so this routine is rarely needed. 9622999313aSBarry Smith 9632999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 9642999313aSBarry Smith decreased by one. 9652999313aSBarry Smith 9662999313aSBarry Smith Level: developer 9672999313aSBarry Smith 9682999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 9692999313aSBarry Smith 9702999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 9712999313aSBarry Smith @*/ 9727087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 9732999313aSBarry Smith { 9742999313aSBarry Smith PetscErrorCode ierr; 9752999313aSBarry Smith 9762999313aSBarry Smith PetscFunctionBegin; 9770700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9780700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 9792999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 9807dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 981906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 9822999313aSBarry Smith snes->ksp = ksp; 9832999313aSBarry Smith PetscFunctionReturn(0); 9842999313aSBarry Smith } 9852999313aSBarry Smith 9867adad957SLisandro Dalcin #if 0 9872999313aSBarry Smith #undef __FUNCT__ 9884a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 9896849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 990e24b481bSBarry Smith { 991e24b481bSBarry Smith PetscFunctionBegin; 992e24b481bSBarry Smith PetscFunctionReturn(0); 993e24b481bSBarry Smith } 9947adad957SLisandro Dalcin #endif 995e24b481bSBarry Smith 9969b94acceSBarry Smith /* -----------------------------------------------------------*/ 9974a2ae208SSatish Balay #undef __FUNCT__ 9984a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 99952baeb72SSatish Balay /*@ 10009b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 10019b94acceSBarry Smith 1002c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1003c7afd0dbSLois Curfman McInnes 1004c7afd0dbSLois Curfman McInnes Input Parameters: 1005906ed7ccSBarry Smith . comm - MPI communicator 10069b94acceSBarry Smith 10079b94acceSBarry Smith Output Parameter: 10089b94acceSBarry Smith . outsnes - the new SNES context 10099b94acceSBarry Smith 1010c7afd0dbSLois Curfman McInnes Options Database Keys: 1011c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1012c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1013c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1014c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1015c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1016c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1017c1f60f51SBarry Smith 101836851e7fSLois Curfman McInnes Level: beginner 101936851e7fSLois Curfman McInnes 10209b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 10219b94acceSBarry Smith 1022a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1023a8054027SBarry Smith 10249b94acceSBarry Smith @*/ 10257087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 10269b94acceSBarry Smith { 1027dfbe8321SBarry Smith PetscErrorCode ierr; 10289b94acceSBarry Smith SNES snes; 1029fa9f3622SBarry Smith SNESKSPEW *kctx; 103037fcc0dbSBarry Smith 10313a40ed3dSBarry Smith PetscFunctionBegin; 1032ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 10338ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 10348ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 10358ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 10368ba1e511SMatthew Knepley #endif 10378ba1e511SMatthew Knepley 10380700a824SBarry Smith ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 10397adad957SLisandro Dalcin 104085385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 10419b94acceSBarry Smith snes->max_its = 50; 10429750a799SBarry Smith snes->max_funcs = 10000; 10439b94acceSBarry Smith snes->norm = 0.0; 1044b4874afaSBarry Smith snes->rtol = 1.e-8; 1045b4874afaSBarry Smith snes->ttol = 0.0; 104670441072SBarry Smith snes->abstol = 1.e-50; 10479b94acceSBarry Smith snes->xtol = 1.e-8; 10484b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 10499b94acceSBarry Smith snes->nfuncs = 0; 105050ffb88aSMatthew Knepley snes->numFailures = 0; 105150ffb88aSMatthew Knepley snes->maxFailures = 1; 10527a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1053e35cf81dSBarry Smith snes->lagjacobian = 1; 1054a8054027SBarry Smith snes->lagpreconditioner = 1; 1055639f9d9dSBarry Smith snes->numbermonitors = 0; 10569b94acceSBarry Smith snes->data = 0; 10574dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1058186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 10596f24a144SLois Curfman McInnes snes->nwork = 0; 106058c9b817SLisandro Dalcin snes->work = 0; 106158c9b817SLisandro Dalcin snes->nvwork = 0; 106258c9b817SLisandro Dalcin snes->vwork = 0; 1063758f92a0SBarry Smith snes->conv_hist_len = 0; 1064758f92a0SBarry Smith snes->conv_hist_max = 0; 1065758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1066758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1067758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1068184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 10699b94acceSBarry Smith 10703d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 10713d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 10723d4c4710SBarry Smith 10739b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 107438f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 10759b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 10769b94acceSBarry Smith kctx->version = 2; 10779b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 10789b94acceSBarry Smith this was too large for some test cases */ 107975567043SBarry Smith kctx->rtol_last = 0.0; 10809b94acceSBarry Smith kctx->rtol_max = .9; 10819b94acceSBarry Smith kctx->gamma = 1.0; 108271f87433Sdalcinl kctx->alpha = .5*(1.0 + sqrt(5.0)); 108371f87433Sdalcinl kctx->alpha2 = kctx->alpha; 10849b94acceSBarry Smith kctx->threshold = .1; 108575567043SBarry Smith kctx->lresid_last = 0.0; 108675567043SBarry Smith kctx->norm_last = 0.0; 10879b94acceSBarry Smith 10889b94acceSBarry Smith *outsnes = snes; 10893a40ed3dSBarry Smith PetscFunctionReturn(0); 10909b94acceSBarry Smith } 10919b94acceSBarry Smith 10924a2ae208SSatish Balay #undef __FUNCT__ 10934a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 10949b94acceSBarry Smith /*@C 10959b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 10969b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 10979b94acceSBarry Smith equations. 10989b94acceSBarry Smith 10993f9fe445SBarry Smith Logically Collective on SNES 1100fee21e36SBarry Smith 1101c7afd0dbSLois Curfman McInnes Input Parameters: 1102c7afd0dbSLois Curfman McInnes + snes - the SNES context 1103c7afd0dbSLois Curfman McInnes . r - vector to store function value 1104de044059SHong Zhang . func - function evaluation routine 1105c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1106c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 11079b94acceSBarry Smith 1108c7afd0dbSLois Curfman McInnes Calling sequence of func: 11098d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1110c7afd0dbSLois Curfman McInnes 1111313e4042SLois Curfman McInnes . f - function vector 1112c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 11139b94acceSBarry Smith 11149b94acceSBarry Smith Notes: 11159b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 11169b94acceSBarry Smith $ f'(x) x = -f(x), 1117c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 11189b94acceSBarry Smith 111936851e7fSLois Curfman McInnes Level: beginner 112036851e7fSLois Curfman McInnes 11219b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 11229b94acceSBarry Smith 1123a86d99e1SLois Curfman McInnes .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 11249b94acceSBarry Smith @*/ 11257087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 11269b94acceSBarry Smith { 112785385478SLisandro Dalcin PetscErrorCode ierr; 11283a40ed3dSBarry Smith PetscFunctionBegin; 11290700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1130d2a683ecSLisandro Dalcin if (r) { 1131d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1132d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 113385385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 11346bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 113585385478SLisandro Dalcin snes->vec_func = r; 1136d2a683ecSLisandro Dalcin } else if (!snes->vec_func && snes->dm) { 1137d2a683ecSLisandro Dalcin ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 1138d2a683ecSLisandro Dalcin } 1139d2a683ecSLisandro Dalcin if (func) snes->ops->computefunction = func; 1140d2a683ecSLisandro Dalcin if (ctx) snes->funP = ctx; 11413a40ed3dSBarry Smith PetscFunctionReturn(0); 11429b94acceSBarry Smith } 11439b94acceSBarry Smith 1144d25893d9SBarry Smith #undef __FUNCT__ 1145d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1146d25893d9SBarry Smith /*@C 1147d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1148d25893d9SBarry Smith 1149d25893d9SBarry Smith Logically Collective on SNES 1150d25893d9SBarry Smith 1151d25893d9SBarry Smith Input Parameters: 1152d25893d9SBarry Smith + snes - the SNES context 1153d25893d9SBarry Smith . func - function evaluation routine 1154d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1155d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1156d25893d9SBarry Smith 1157d25893d9SBarry Smith Calling sequence of func: 1158d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1159d25893d9SBarry Smith 1160d25893d9SBarry Smith . f - function vector 1161d25893d9SBarry Smith - ctx - optional user-defined function context 1162d25893d9SBarry Smith 1163d25893d9SBarry Smith Level: intermediate 1164d25893d9SBarry Smith 1165d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1166d25893d9SBarry Smith 1167d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1168d25893d9SBarry Smith @*/ 1169d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1170d25893d9SBarry Smith { 1171d25893d9SBarry Smith PetscFunctionBegin; 1172d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1173d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1174d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1175d25893d9SBarry Smith PetscFunctionReturn(0); 1176d25893d9SBarry Smith } 1177d25893d9SBarry Smith 11783ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 11793ab0aad5SBarry Smith #undef __FUNCT__ 11801096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 11811096aae1SMatthew Knepley /*@C 11821096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 11831096aae1SMatthew Knepley it assumes a zero right hand side. 11841096aae1SMatthew Knepley 11853f9fe445SBarry Smith Logically Collective on SNES 11861096aae1SMatthew Knepley 11871096aae1SMatthew Knepley Input Parameter: 11881096aae1SMatthew Knepley . snes - the SNES context 11891096aae1SMatthew Knepley 11901096aae1SMatthew Knepley Output Parameter: 1191bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 11921096aae1SMatthew Knepley 11931096aae1SMatthew Knepley Level: intermediate 11941096aae1SMatthew Knepley 11951096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 11961096aae1SMatthew Knepley 119785385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 11981096aae1SMatthew Knepley @*/ 11997087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 12001096aae1SMatthew Knepley { 12011096aae1SMatthew Knepley PetscFunctionBegin; 12020700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12031096aae1SMatthew Knepley PetscValidPointer(rhs,2); 120485385478SLisandro Dalcin *rhs = snes->vec_rhs; 12051096aae1SMatthew Knepley PetscFunctionReturn(0); 12061096aae1SMatthew Knepley } 12071096aae1SMatthew Knepley 12081096aae1SMatthew Knepley #undef __FUNCT__ 12094a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 12109b94acceSBarry Smith /*@ 121136851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 12129b94acceSBarry Smith SNESSetFunction(). 12139b94acceSBarry Smith 1214c7afd0dbSLois Curfman McInnes Collective on SNES 1215c7afd0dbSLois Curfman McInnes 12169b94acceSBarry Smith Input Parameters: 1217c7afd0dbSLois Curfman McInnes + snes - the SNES context 1218c7afd0dbSLois Curfman McInnes - x - input vector 12199b94acceSBarry Smith 12209b94acceSBarry Smith Output Parameter: 12213638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 12229b94acceSBarry Smith 12231bffabb2SLois Curfman McInnes Notes: 122436851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 122536851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 122636851e7fSLois Curfman McInnes themselves. 122736851e7fSLois Curfman McInnes 122836851e7fSLois Curfman McInnes Level: developer 122936851e7fSLois Curfman McInnes 12309b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 12319b94acceSBarry Smith 1232a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 12339b94acceSBarry Smith @*/ 12347087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 12359b94acceSBarry Smith { 1236dfbe8321SBarry Smith PetscErrorCode ierr; 12379b94acceSBarry Smith 12383a40ed3dSBarry Smith PetscFunctionBegin; 12390700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12400700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 12410700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1242c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1243c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 1244184914b5SBarry Smith 1245d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 1246e7788613SBarry Smith if (snes->ops->computefunction) { 1247d64ed03dSBarry Smith PetscStackPush("SNES user function"); 124839d508bbSBarry Smith ierr = (*snes->ops->computefunction)(snes,x,y,snes->funP);CHKERRQ(ierr); 1249d64ed03dSBarry Smith PetscStackPop; 125085385478SLisandro Dalcin } else if (snes->vec_rhs) { 12511096aae1SMatthew Knepley ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 125273250ac0SBarry Smith } else if (snes->dm) { 1253644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1254644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 125585385478SLisandro Dalcin if (snes->vec_rhs) { 125685385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 12573ab0aad5SBarry Smith } 1258ae3c334cSLois Curfman McInnes snes->nfuncs++; 1259d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 12603a40ed3dSBarry Smith PetscFunctionReturn(0); 12619b94acceSBarry Smith } 12629b94acceSBarry Smith 12634a2ae208SSatish Balay #undef __FUNCT__ 12644a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 126562fef451SLois Curfman McInnes /*@ 126662fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 126762fef451SLois Curfman McInnes set with SNESSetJacobian(). 126862fef451SLois Curfman McInnes 1269c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1270c7afd0dbSLois Curfman McInnes 127162fef451SLois Curfman McInnes Input Parameters: 1272c7afd0dbSLois Curfman McInnes + snes - the SNES context 1273c7afd0dbSLois Curfman McInnes - x - input vector 127462fef451SLois Curfman McInnes 127562fef451SLois Curfman McInnes Output Parameters: 1276c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 127762fef451SLois Curfman McInnes . B - optional preconditioning matrix 12782b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1279fee21e36SBarry Smith 1280e35cf81dSBarry Smith Options Database Keys: 1281e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1282693365a8SJed Brown . -snes_lag_jacobian <lag> 1283693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1284693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1285693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 1286693365a8SJed Brown - -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1287e35cf81dSBarry Smith 128862fef451SLois Curfman McInnes Notes: 128962fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 129062fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 129162fef451SLois Curfman McInnes 129294b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1293dc5a77f8SLois Curfman McInnes flag parameter. 129462fef451SLois Curfman McInnes 129536851e7fSLois Curfman McInnes Level: developer 129636851e7fSLois Curfman McInnes 129762fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 129862fef451SLois Curfman McInnes 1299e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 130062fef451SLois Curfman McInnes @*/ 13017087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 13029b94acceSBarry Smith { 1303dfbe8321SBarry Smith PetscErrorCode ierr; 1304ace3abfcSBarry Smith PetscBool flag; 13053a40ed3dSBarry Smith 13063a40ed3dSBarry Smith PetscFunctionBegin; 13070700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13080700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 13094482741eSBarry Smith PetscValidPointer(flg,5); 1310c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 1311e7788613SBarry Smith if (!snes->ops->computejacobian) PetscFunctionReturn(0); 1312ebd3b9afSBarry Smith 1313ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1314ebd3b9afSBarry Smith 1315fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 1316fe3ffe1eSBarry Smith snes->lagjacobian = -1; 1317fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1318fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 1319e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1320e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1321ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1322ebd3b9afSBarry Smith if (flag) { 1323ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1324ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1325ebd3b9afSBarry Smith } 1326e35cf81dSBarry Smith PetscFunctionReturn(0); 1327e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1328e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1329e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1330ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1331ebd3b9afSBarry Smith if (flag) { 1332ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1333ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1334ebd3b9afSBarry Smith } 1335e35cf81dSBarry Smith PetscFunctionReturn(0); 1336e35cf81dSBarry Smith } 1337e35cf81dSBarry Smith 1338c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 1339e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1340d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 1341e7788613SBarry Smith ierr = (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);CHKERRQ(ierr); 1342d64ed03dSBarry Smith PetscStackPop; 1343d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1344a8054027SBarry Smith 13453b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 13463b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 13473b4f5425SBarry Smith snes->lagpreconditioner = -1; 13483b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 1349a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1350a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 1351a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 1352a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1353a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 1354a8054027SBarry Smith } 1355a8054027SBarry Smith 13566d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 13570700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 13580700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 1359693365a8SJed Brown { 1360693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 1361693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 1362693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 1363693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 1364693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 1365693365a8SJed Brown if (flag || flag_draw || flag_contour) { 1366693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 1367693365a8SJed Brown MatStructure mstruct; 1368693365a8SJed Brown PetscViewer vdraw,vstdout; 13696b3a5b13SJed Brown PetscBool flg; 1370693365a8SJed Brown if (flag_operator) { 1371693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 1372693365a8SJed Brown Bexp = Bexp_mine; 1373693365a8SJed Brown } else { 1374693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 1375693365a8SJed Brown ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 1376693365a8SJed Brown if (flg) Bexp = *B; 1377693365a8SJed Brown else { 1378693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 1379693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 1380693365a8SJed Brown Bexp = Bexp_mine; 1381693365a8SJed Brown } 1382693365a8SJed Brown } 1383693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 1384693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 1385693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 1386693365a8SJed Brown if (flag_draw || flag_contour) { 1387693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 1388693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 1389693365a8SJed Brown } else vdraw = PETSC_NULL; 1390693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 1391693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 1392693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 1393693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 1394693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1395693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 1396693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1397693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 1398693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1399693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 1400693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 1401693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 1402693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 1403693365a8SJed Brown } 1404693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 1405693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 1406693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 1407693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 1408693365a8SJed Brown } 1409693365a8SJed Brown } 14103a40ed3dSBarry Smith PetscFunctionReturn(0); 14119b94acceSBarry Smith } 14129b94acceSBarry Smith 14134a2ae208SSatish Balay #undef __FUNCT__ 14144a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 14159b94acceSBarry Smith /*@C 14169b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 1417044dda88SLois Curfman McInnes location to store the matrix. 14189b94acceSBarry Smith 14193f9fe445SBarry Smith Logically Collective on SNES and Mat 1420c7afd0dbSLois Curfman McInnes 14219b94acceSBarry Smith Input Parameters: 1422c7afd0dbSLois Curfman McInnes + snes - the SNES context 14239b94acceSBarry Smith . A - Jacobian matrix 14249b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 1425efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 1426c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1427efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 14289b94acceSBarry Smith 14299b94acceSBarry Smith Calling sequence of func: 14308d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 14319b94acceSBarry Smith 1432c7afd0dbSLois Curfman McInnes + x - input vector 14339b94acceSBarry Smith . A - Jacobian matrix 14349b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 1435ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 14362b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 1437c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 14389b94acceSBarry Smith 14399b94acceSBarry Smith Notes: 144094b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 14412cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 1442ac21db08SLois Curfman McInnes 1443ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 14449b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 14459b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 14469b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 14479b94acceSBarry Smith throughout the global iterations. 14489b94acceSBarry Smith 144916913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 145016913363SBarry Smith each matrix. 145116913363SBarry Smith 1452a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 1453a8a26c1eSJed Brown must be a MatFDColoring. 1454a8a26c1eSJed Brown 145536851e7fSLois Curfman McInnes Level: beginner 145636851e7fSLois Curfman McInnes 14579b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 14589b94acceSBarry Smith 14593ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 14609b94acceSBarry Smith @*/ 14617087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 14629b94acceSBarry Smith { 1463dfbe8321SBarry Smith PetscErrorCode ierr; 14643a7fca6bSBarry Smith 14653a40ed3dSBarry Smith PetscFunctionBegin; 14660700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14670700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 14680700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 1469c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 147006975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 1471e7788613SBarry Smith if (func) snes->ops->computejacobian = func; 14723a7fca6bSBarry Smith if (ctx) snes->jacP = ctx; 14733a7fca6bSBarry Smith if (A) { 14747dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 14756bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 14769b94acceSBarry Smith snes->jacobian = A; 14773a7fca6bSBarry Smith } 14783a7fca6bSBarry Smith if (B) { 14797dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 14806bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 14819b94acceSBarry Smith snes->jacobian_pre = B; 14823a7fca6bSBarry Smith } 14833a40ed3dSBarry Smith PetscFunctionReturn(0); 14849b94acceSBarry Smith } 148562fef451SLois Curfman McInnes 14864a2ae208SSatish Balay #undef __FUNCT__ 14874a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 1488c2aafc4cSSatish Balay /*@C 1489b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 1490b4fd4287SBarry Smith provided context for evaluating the Jacobian. 1491b4fd4287SBarry Smith 1492c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 1493c7afd0dbSLois Curfman McInnes 1494b4fd4287SBarry Smith Input Parameter: 1495b4fd4287SBarry Smith . snes - the nonlinear solver context 1496b4fd4287SBarry Smith 1497b4fd4287SBarry Smith Output Parameters: 1498c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 1499b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 150070e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 150170e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 1502fee21e36SBarry Smith 150336851e7fSLois Curfman McInnes Level: advanced 150436851e7fSLois Curfman McInnes 1505b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 1506b4fd4287SBarry Smith @*/ 15077087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 1508b4fd4287SBarry Smith { 15093a40ed3dSBarry Smith PetscFunctionBegin; 15100700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1511b4fd4287SBarry Smith if (A) *A = snes->jacobian; 1512b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 1513e7788613SBarry Smith if (func) *func = snes->ops->computejacobian; 151470e92668SMatthew Knepley if (ctx) *ctx = snes->jacP; 15153a40ed3dSBarry Smith PetscFunctionReturn(0); 1516b4fd4287SBarry Smith } 1517b4fd4287SBarry Smith 15189b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 15199b94acceSBarry Smith 15204a2ae208SSatish Balay #undef __FUNCT__ 15214a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 15229b94acceSBarry Smith /*@ 15239b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 1524272ac6f2SLois Curfman McInnes of a nonlinear solver. 15259b94acceSBarry Smith 1526fee21e36SBarry Smith Collective on SNES 1527fee21e36SBarry Smith 1528c7afd0dbSLois Curfman McInnes Input Parameters: 152970e92668SMatthew Knepley . snes - the SNES context 1530c7afd0dbSLois Curfman McInnes 1531272ac6f2SLois Curfman McInnes Notes: 1532272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 1533272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 1534272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 1535272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 1536272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 1537272ac6f2SLois Curfman McInnes 153836851e7fSLois Curfman McInnes Level: advanced 153936851e7fSLois Curfman McInnes 15409b94acceSBarry Smith .keywords: SNES, nonlinear, setup 15419b94acceSBarry Smith 15429b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 15439b94acceSBarry Smith @*/ 15447087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 15459b94acceSBarry Smith { 1546dfbe8321SBarry Smith PetscErrorCode ierr; 15473a40ed3dSBarry Smith 15483a40ed3dSBarry Smith PetscFunctionBegin; 15490700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15504dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 15519b94acceSBarry Smith 15527adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 155385385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 155485385478SLisandro Dalcin } 155585385478SLisandro Dalcin 1556efd51863SBarry Smith if (!snes->vec_func && snes->dm && !snes->vec_rhs) { 1557efd51863SBarry Smith ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 1558efd51863SBarry Smith } 155917186662SBarry Smith if (!snes->vec_func && !snes->vec_rhs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first"); 1560644e2e5bSBarry Smith if (!snes->ops->computefunction && !snes->vec_rhs && !snes->dm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() or SNESSetDM() first"); 156117186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 156258c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 156358c9b817SLisandro Dalcin 156458c9b817SLisandro Dalcin if (!snes->vec_func && snes->vec_rhs) { 156558c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_rhs, &snes->vec_func);CHKERRQ(ierr); 156658c9b817SLisandro Dalcin } 156758c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 156858c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 156958c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 157058c9b817SLisandro Dalcin } 157158c9b817SLisandro Dalcin 1572ef8dffc7SBarry Smith if (!snes->ops->computejacobian && snes->dm) { 1573ef8dffc7SBarry Smith Mat J; 1574ef8dffc7SBarry Smith ierr = DMGetMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr); 1575cab2e9ccSBarry Smith ierr = SNESSetJacobian(snes,J,J,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr); 1576cab2e9ccSBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 1577a8248277SBarry Smith } else if (snes->ops->computejacobian == MatMFFDComputeJacobian) { 1578a8248277SBarry Smith Mat J; 1579a8248277SBarry Smith ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 1580a8248277SBarry Smith ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 1581a8248277SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 1582a8248277SBarry Smith ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);CHKERRQ(ierr); 1583a8248277SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 1584a8248277SBarry Smith } else if (snes->dm && snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 1585a8248277SBarry Smith Mat J,B; 1586a8248277SBarry Smith ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 1587a8248277SBarry Smith ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 1588a8248277SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 1589a8248277SBarry Smith ierr = DMGetMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 1590a8248277SBarry Smith ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,snes->funP);CHKERRQ(ierr); 1591a8248277SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 1592a8248277SBarry Smith ierr = MatDestroy(&B);CHKERRQ(ierr); 1593efd51863SBarry Smith } else if (snes->dm && !snes->jacobian_pre){ 1594efd51863SBarry Smith Mat J; 1595efd51863SBarry Smith ierr = DMGetMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr); 1596*3cbb28f5SBarry Smith ierr = SNESSetJacobian(snes,J,J,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1597efd51863SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 1598ef8dffc7SBarry Smith } 1599efd51863SBarry Smith 1600b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 1601b710008aSBarry Smith 1602d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 1603d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 1604d25893d9SBarry Smith } 1605d25893d9SBarry Smith 1606410397dcSLisandro Dalcin if (snes->ops->setup) { 1607410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 1608410397dcSLisandro Dalcin } 160958c9b817SLisandro Dalcin 16107aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 16113a40ed3dSBarry Smith PetscFunctionReturn(0); 16129b94acceSBarry Smith } 16139b94acceSBarry Smith 16144a2ae208SSatish Balay #undef __FUNCT__ 161537596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 161637596af1SLisandro Dalcin /*@ 161737596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 161837596af1SLisandro Dalcin 161937596af1SLisandro Dalcin Collective on SNES 162037596af1SLisandro Dalcin 162137596af1SLisandro Dalcin Input Parameter: 162237596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 162337596af1SLisandro Dalcin 1624d25893d9SBarry Smith Level: intermediate 1625d25893d9SBarry Smith 1626d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 162737596af1SLisandro Dalcin 162837596af1SLisandro Dalcin .keywords: SNES, destroy 162937596af1SLisandro Dalcin 163037596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 163137596af1SLisandro Dalcin @*/ 163237596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 163337596af1SLisandro Dalcin { 163437596af1SLisandro Dalcin PetscErrorCode ierr; 163537596af1SLisandro Dalcin 163637596af1SLisandro Dalcin PetscFunctionBegin; 163737596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1638d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 1639d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 1640d25893d9SBarry Smith snes->user = PETSC_NULL; 1641d25893d9SBarry Smith } 1642644e2e5bSBarry Smith if (snes->ops->computejacobian == SNESDefaultComputeJacobianColor && snes->dm) { 1643644e2e5bSBarry Smith ierr = MatFDColoringDestroy((MatFDColoring*)&snes->jacP);CHKERRQ(ierr); 1644644e2e5bSBarry Smith snes->ops->computejacobian = PETSC_NULL; 1645644e2e5bSBarry Smith } 1646d25893d9SBarry Smith 164737596af1SLisandro Dalcin if (snes->ops->reset) { 164837596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 164937596af1SLisandro Dalcin } 165037596af1SLisandro Dalcin if (snes->ksp) {ierr = KSPReset(snes->ksp);CHKERRQ(ierr);} 16516bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 16526bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 16536bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 16546bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 16556bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 16566bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 165737596af1SLisandro Dalcin if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);} 165837596af1SLisandro Dalcin if (snes->vwork) {ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);} 165937596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 166037596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 166137596af1SLisandro Dalcin PetscFunctionReturn(0); 166237596af1SLisandro Dalcin } 166337596af1SLisandro Dalcin 166437596af1SLisandro Dalcin #undef __FUNCT__ 16654a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 166652baeb72SSatish Balay /*@ 16679b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 16689b94acceSBarry Smith with SNESCreate(). 16699b94acceSBarry Smith 1670c7afd0dbSLois Curfman McInnes Collective on SNES 1671c7afd0dbSLois Curfman McInnes 16729b94acceSBarry Smith Input Parameter: 16739b94acceSBarry Smith . snes - the SNES context 16749b94acceSBarry Smith 167536851e7fSLois Curfman McInnes Level: beginner 167636851e7fSLois Curfman McInnes 16779b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 16789b94acceSBarry Smith 167963a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 16809b94acceSBarry Smith @*/ 16816bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 16829b94acceSBarry Smith { 16836849ba73SBarry Smith PetscErrorCode ierr; 16843a40ed3dSBarry Smith 16853a40ed3dSBarry Smith PetscFunctionBegin; 16866bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 16876bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 16886bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 1689d4bb536fSBarry Smith 16906bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 16916b8b9a38SLisandro Dalcin 1692be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 16936bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 16946bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 16956d4c513bSLisandro Dalcin 16966bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 16976bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 16986b8b9a38SLisandro Dalcin 16996bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 17006bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 17016bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 17026b8b9a38SLisandro Dalcin } 17036bf464f9SBarry Smith if ((*snes)->conv_malloc) { 17046bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 17056bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 170658c9b817SLisandro Dalcin } 17076bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 1708a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 17093a40ed3dSBarry Smith PetscFunctionReturn(0); 17109b94acceSBarry Smith } 17119b94acceSBarry Smith 17129b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 17139b94acceSBarry Smith 17144a2ae208SSatish Balay #undef __FUNCT__ 1715a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 1716a8054027SBarry Smith /*@ 1717a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 1718a8054027SBarry Smith 17193f9fe445SBarry Smith Logically Collective on SNES 1720a8054027SBarry Smith 1721a8054027SBarry Smith Input Parameters: 1722a8054027SBarry Smith + snes - the SNES context 1723a8054027SBarry 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 17243b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 1725a8054027SBarry Smith 1726a8054027SBarry Smith Options Database Keys: 1727a8054027SBarry Smith . -snes_lag_preconditioner <lag> 1728a8054027SBarry Smith 1729a8054027SBarry Smith Notes: 1730a8054027SBarry Smith The default is 1 1731a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1732a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 1733a8054027SBarry Smith 1734a8054027SBarry Smith Level: intermediate 1735a8054027SBarry Smith 1736a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 1737a8054027SBarry Smith 1738e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 1739a8054027SBarry Smith 1740a8054027SBarry Smith @*/ 17417087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 1742a8054027SBarry Smith { 1743a8054027SBarry Smith PetscFunctionBegin; 17440700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1745e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 1746e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 1747c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 1748a8054027SBarry Smith snes->lagpreconditioner = lag; 1749a8054027SBarry Smith PetscFunctionReturn(0); 1750a8054027SBarry Smith } 1751a8054027SBarry Smith 1752a8054027SBarry Smith #undef __FUNCT__ 1753efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 1754efd51863SBarry Smith /*@ 1755efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 1756efd51863SBarry Smith 1757efd51863SBarry Smith Logically Collective on SNES 1758efd51863SBarry Smith 1759efd51863SBarry Smith Input Parameters: 1760efd51863SBarry Smith + snes - the SNES context 1761efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 1762efd51863SBarry Smith 1763efd51863SBarry Smith Options Database Keys: 1764efd51863SBarry Smith . -snes_grid_sequence <steps> 1765efd51863SBarry Smith 1766efd51863SBarry Smith Level: intermediate 1767efd51863SBarry Smith 1768efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 1769efd51863SBarry Smith 1770efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 1771efd51863SBarry Smith 1772efd51863SBarry Smith @*/ 1773efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 1774efd51863SBarry Smith { 1775efd51863SBarry Smith PetscFunctionBegin; 1776efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1777efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 1778efd51863SBarry Smith snes->gridsequence = steps; 1779efd51863SBarry Smith PetscFunctionReturn(0); 1780efd51863SBarry Smith } 1781efd51863SBarry Smith 1782efd51863SBarry Smith #undef __FUNCT__ 1783a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 1784a8054027SBarry Smith /*@ 1785a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 1786a8054027SBarry Smith 17873f9fe445SBarry Smith Not Collective 1788a8054027SBarry Smith 1789a8054027SBarry Smith Input Parameter: 1790a8054027SBarry Smith . snes - the SNES context 1791a8054027SBarry Smith 1792a8054027SBarry Smith Output Parameter: 1793a8054027SBarry 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 17943b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 1795a8054027SBarry Smith 1796a8054027SBarry Smith Options Database Keys: 1797a8054027SBarry Smith . -snes_lag_preconditioner <lag> 1798a8054027SBarry Smith 1799a8054027SBarry Smith Notes: 1800a8054027SBarry Smith The default is 1 1801a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1802a8054027SBarry Smith 1803a8054027SBarry Smith Level: intermediate 1804a8054027SBarry Smith 1805a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 1806a8054027SBarry Smith 1807a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 1808a8054027SBarry Smith 1809a8054027SBarry Smith @*/ 18107087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 1811a8054027SBarry Smith { 1812a8054027SBarry Smith PetscFunctionBegin; 18130700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1814a8054027SBarry Smith *lag = snes->lagpreconditioner; 1815a8054027SBarry Smith PetscFunctionReturn(0); 1816a8054027SBarry Smith } 1817a8054027SBarry Smith 1818a8054027SBarry Smith #undef __FUNCT__ 1819e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 1820e35cf81dSBarry Smith /*@ 1821e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 1822e35cf81dSBarry Smith often the preconditioner is rebuilt. 1823e35cf81dSBarry Smith 18243f9fe445SBarry Smith Logically Collective on SNES 1825e35cf81dSBarry Smith 1826e35cf81dSBarry Smith Input Parameters: 1827e35cf81dSBarry Smith + snes - the SNES context 1828e35cf81dSBarry 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 1829fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 1830e35cf81dSBarry Smith 1831e35cf81dSBarry Smith Options Database Keys: 1832e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 1833e35cf81dSBarry Smith 1834e35cf81dSBarry Smith Notes: 1835e35cf81dSBarry Smith The default is 1 1836e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1837fe3ffe1eSBarry 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 1838fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 1839e35cf81dSBarry Smith 1840e35cf81dSBarry Smith Level: intermediate 1841e35cf81dSBarry Smith 1842e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 1843e35cf81dSBarry Smith 1844e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 1845e35cf81dSBarry Smith 1846e35cf81dSBarry Smith @*/ 18477087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 1848e35cf81dSBarry Smith { 1849e35cf81dSBarry Smith PetscFunctionBegin; 18500700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1851e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 1852e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 1853c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 1854e35cf81dSBarry Smith snes->lagjacobian = lag; 1855e35cf81dSBarry Smith PetscFunctionReturn(0); 1856e35cf81dSBarry Smith } 1857e35cf81dSBarry Smith 1858e35cf81dSBarry Smith #undef __FUNCT__ 1859e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 1860e35cf81dSBarry Smith /*@ 1861e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 1862e35cf81dSBarry Smith 18633f9fe445SBarry Smith Not Collective 1864e35cf81dSBarry Smith 1865e35cf81dSBarry Smith Input Parameter: 1866e35cf81dSBarry Smith . snes - the SNES context 1867e35cf81dSBarry Smith 1868e35cf81dSBarry Smith Output Parameter: 1869e35cf81dSBarry 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 1870e35cf81dSBarry Smith the Jacobian is built etc. 1871e35cf81dSBarry Smith 1872e35cf81dSBarry Smith Options Database Keys: 1873e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 1874e35cf81dSBarry Smith 1875e35cf81dSBarry Smith Notes: 1876e35cf81dSBarry Smith The default is 1 1877e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1878e35cf81dSBarry Smith 1879e35cf81dSBarry Smith Level: intermediate 1880e35cf81dSBarry Smith 1881e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 1882e35cf81dSBarry Smith 1883e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 1884e35cf81dSBarry Smith 1885e35cf81dSBarry Smith @*/ 18867087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 1887e35cf81dSBarry Smith { 1888e35cf81dSBarry Smith PetscFunctionBegin; 18890700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1890e35cf81dSBarry Smith *lag = snes->lagjacobian; 1891e35cf81dSBarry Smith PetscFunctionReturn(0); 1892e35cf81dSBarry Smith } 1893e35cf81dSBarry Smith 1894e35cf81dSBarry Smith #undef __FUNCT__ 18954a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 18969b94acceSBarry Smith /*@ 1897d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 18989b94acceSBarry Smith 18993f9fe445SBarry Smith Logically Collective on SNES 1900c7afd0dbSLois Curfman McInnes 19019b94acceSBarry Smith Input Parameters: 1902c7afd0dbSLois Curfman McInnes + snes - the SNES context 190370441072SBarry Smith . abstol - absolute convergence tolerance 190433174efeSLois Curfman McInnes . rtol - relative convergence tolerance 190533174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 190633174efeSLois Curfman McInnes of the change in the solution between steps 190733174efeSLois Curfman McInnes . maxit - maximum number of iterations 1908c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 1909fee21e36SBarry Smith 191033174efeSLois Curfman McInnes Options Database Keys: 191170441072SBarry Smith + -snes_atol <abstol> - Sets abstol 1912c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 1913c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 1914c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 1915c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 19169b94acceSBarry Smith 1917d7a720efSLois Curfman McInnes Notes: 19189b94acceSBarry Smith The default maximum number of iterations is 50. 19199b94acceSBarry Smith The default maximum number of function evaluations is 1000. 19209b94acceSBarry Smith 192136851e7fSLois Curfman McInnes Level: intermediate 192236851e7fSLois Curfman McInnes 192333174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 19249b94acceSBarry Smith 19252492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 19269b94acceSBarry Smith @*/ 19277087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 19289b94acceSBarry Smith { 19293a40ed3dSBarry Smith PetscFunctionBegin; 19300700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1931c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 1932c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 1933c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 1934c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 1935c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 1936c5eb9154SBarry Smith 193770441072SBarry Smith if (abstol != PETSC_DEFAULT) snes->abstol = abstol; 1938d7a720efSLois Curfman McInnes if (rtol != PETSC_DEFAULT) snes->rtol = rtol; 1939d7a720efSLois Curfman McInnes if (stol != PETSC_DEFAULT) snes->xtol = stol; 1940d7a720efSLois Curfman McInnes if (maxit != PETSC_DEFAULT) snes->max_its = maxit; 1941d7a720efSLois Curfman McInnes if (maxf != PETSC_DEFAULT) snes->max_funcs = maxf; 19423a40ed3dSBarry Smith PetscFunctionReturn(0); 19439b94acceSBarry Smith } 19449b94acceSBarry Smith 19454a2ae208SSatish Balay #undef __FUNCT__ 19464a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 19479b94acceSBarry Smith /*@ 194833174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 194933174efeSLois Curfman McInnes 1950c7afd0dbSLois Curfman McInnes Not Collective 1951c7afd0dbSLois Curfman McInnes 195233174efeSLois Curfman McInnes Input Parameters: 1953c7afd0dbSLois Curfman McInnes + snes - the SNES context 195485385478SLisandro Dalcin . atol - absolute convergence tolerance 195533174efeSLois Curfman McInnes . rtol - relative convergence tolerance 195633174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 195733174efeSLois Curfman McInnes of the change in the solution between steps 195833174efeSLois Curfman McInnes . maxit - maximum number of iterations 1959c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 1960fee21e36SBarry Smith 196133174efeSLois Curfman McInnes Notes: 196233174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 196333174efeSLois Curfman McInnes 196436851e7fSLois Curfman McInnes Level: intermediate 196536851e7fSLois Curfman McInnes 196633174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 196733174efeSLois Curfman McInnes 196833174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 196933174efeSLois Curfman McInnes @*/ 19707087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 197133174efeSLois Curfman McInnes { 19723a40ed3dSBarry Smith PetscFunctionBegin; 19730700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 197485385478SLisandro Dalcin if (atol) *atol = snes->abstol; 197533174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 197633174efeSLois Curfman McInnes if (stol) *stol = snes->xtol; 197733174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 197833174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 19793a40ed3dSBarry Smith PetscFunctionReturn(0); 198033174efeSLois Curfman McInnes } 198133174efeSLois Curfman McInnes 19824a2ae208SSatish Balay #undef __FUNCT__ 19834a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 198433174efeSLois Curfman McInnes /*@ 19859b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 19869b94acceSBarry Smith 19873f9fe445SBarry Smith Logically Collective on SNES 1988fee21e36SBarry Smith 1989c7afd0dbSLois Curfman McInnes Input Parameters: 1990c7afd0dbSLois Curfman McInnes + snes - the SNES context 1991c7afd0dbSLois Curfman McInnes - tol - tolerance 1992c7afd0dbSLois Curfman McInnes 19939b94acceSBarry Smith Options Database Key: 1994c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 19959b94acceSBarry Smith 199636851e7fSLois Curfman McInnes Level: intermediate 199736851e7fSLois Curfman McInnes 19989b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 19999b94acceSBarry Smith 20002492ecdbSBarry Smith .seealso: SNESSetTolerances() 20019b94acceSBarry Smith @*/ 20027087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 20039b94acceSBarry Smith { 20043a40ed3dSBarry Smith PetscFunctionBegin; 20050700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2006c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 20079b94acceSBarry Smith snes->deltatol = tol; 20083a40ed3dSBarry Smith PetscFunctionReturn(0); 20099b94acceSBarry Smith } 20109b94acceSBarry Smith 2011df9fa365SBarry Smith /* 2012df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2013df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2014df9fa365SBarry Smith macros instead of functions 2015df9fa365SBarry Smith */ 20164a2ae208SSatish Balay #undef __FUNCT__ 2017a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 20187087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2019ce1608b8SBarry Smith { 2020dfbe8321SBarry Smith PetscErrorCode ierr; 2021ce1608b8SBarry Smith 2022ce1608b8SBarry Smith PetscFunctionBegin; 20230700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2024a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2025ce1608b8SBarry Smith PetscFunctionReturn(0); 2026ce1608b8SBarry Smith } 2027ce1608b8SBarry Smith 20284a2ae208SSatish Balay #undef __FUNCT__ 2029a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 20307087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2031df9fa365SBarry Smith { 2032dfbe8321SBarry Smith PetscErrorCode ierr; 2033df9fa365SBarry Smith 2034df9fa365SBarry Smith PetscFunctionBegin; 2035a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2036df9fa365SBarry Smith PetscFunctionReturn(0); 2037df9fa365SBarry Smith } 2038df9fa365SBarry Smith 20394a2ae208SSatish Balay #undef __FUNCT__ 2040a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 20416bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2042df9fa365SBarry Smith { 2043dfbe8321SBarry Smith PetscErrorCode ierr; 2044df9fa365SBarry Smith 2045df9fa365SBarry Smith PetscFunctionBegin; 2046a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2047df9fa365SBarry Smith PetscFunctionReturn(0); 2048df9fa365SBarry Smith } 2049df9fa365SBarry Smith 20507087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2051b271bb04SBarry Smith #undef __FUNCT__ 2052b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 20537087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2054b271bb04SBarry Smith { 2055b271bb04SBarry Smith PetscDrawLG lg; 2056b271bb04SBarry Smith PetscErrorCode ierr; 2057b271bb04SBarry Smith PetscReal x,y,per; 2058b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2059b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2060b271bb04SBarry Smith PetscDraw draw; 2061b271bb04SBarry Smith PetscFunctionBegin; 2062b271bb04SBarry Smith if (!monctx) { 2063b271bb04SBarry Smith MPI_Comm comm; 2064b271bb04SBarry Smith 2065b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2066b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2067b271bb04SBarry Smith } 2068b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2069b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2070b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2071b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2072b271bb04SBarry Smith x = (PetscReal) n; 2073b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2074b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2075b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2076b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2077b271bb04SBarry Smith } 2078b271bb04SBarry Smith 2079b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2080b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2081b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2082b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2083b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2084b271bb04SBarry Smith x = (PetscReal) n; 2085b271bb04SBarry Smith y = 100.0*per; 2086b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2087b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2088b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2089b271bb04SBarry Smith } 2090b271bb04SBarry Smith 2091b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2092b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2093b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2094b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2095b271bb04SBarry Smith x = (PetscReal) n; 2096b271bb04SBarry Smith y = (prev - rnorm)/prev; 2097b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2098b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2099b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2100b271bb04SBarry Smith } 2101b271bb04SBarry Smith 2102b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2103b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2104b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2105b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2106b271bb04SBarry Smith x = (PetscReal) n; 2107b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2108b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2109b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2110b271bb04SBarry Smith } 2111b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2112b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2113b271bb04SBarry Smith } 2114b271bb04SBarry Smith prev = rnorm; 2115b271bb04SBarry Smith PetscFunctionReturn(0); 2116b271bb04SBarry Smith } 2117b271bb04SBarry Smith 2118b271bb04SBarry Smith #undef __FUNCT__ 2119b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 21207087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2121b271bb04SBarry Smith { 2122b271bb04SBarry Smith PetscErrorCode ierr; 2123b271bb04SBarry Smith 2124b271bb04SBarry Smith PetscFunctionBegin; 2125b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2126b271bb04SBarry Smith PetscFunctionReturn(0); 2127b271bb04SBarry Smith } 2128b271bb04SBarry Smith 2129b271bb04SBarry Smith #undef __FUNCT__ 2130b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 21316bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2132b271bb04SBarry Smith { 2133b271bb04SBarry Smith PetscErrorCode ierr; 2134b271bb04SBarry Smith 2135b271bb04SBarry Smith PetscFunctionBegin; 2136b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2137b271bb04SBarry Smith PetscFunctionReturn(0); 2138b271bb04SBarry Smith } 2139b271bb04SBarry Smith 21407a03ce2fSLisandro Dalcin #undef __FUNCT__ 21417a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 21427a03ce2fSLisandro Dalcin /* 21437a03ce2fSLisandro Dalcin Runs the user provided monitor routines, if they exists. 21447a03ce2fSLisandro Dalcin */ 21457a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 21467a03ce2fSLisandro Dalcin { 21477a03ce2fSLisandro Dalcin PetscErrorCode ierr; 21487a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 21497a03ce2fSLisandro Dalcin 21507a03ce2fSLisandro Dalcin PetscFunctionBegin; 21517a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 21527a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 21537a03ce2fSLisandro Dalcin } 21547a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 21557a03ce2fSLisandro Dalcin } 21567a03ce2fSLisandro Dalcin 21579b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 21589b94acceSBarry Smith 21594a2ae208SSatish Balay #undef __FUNCT__ 2160a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 21619b94acceSBarry Smith /*@C 2162a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 21639b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 21649b94acceSBarry Smith progress. 21659b94acceSBarry Smith 21663f9fe445SBarry Smith Logically Collective on SNES 2167fee21e36SBarry Smith 2168c7afd0dbSLois Curfman McInnes Input Parameters: 2169c7afd0dbSLois Curfman McInnes + snes - the SNES context 2170c7afd0dbSLois Curfman McInnes . func - monitoring routine 2171b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 2172e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 2173b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 2174b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 21759b94acceSBarry Smith 2176c7afd0dbSLois Curfman McInnes Calling sequence of func: 2177a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2178c7afd0dbSLois Curfman McInnes 2179c7afd0dbSLois Curfman McInnes + snes - the SNES context 2180c7afd0dbSLois Curfman McInnes . its - iteration number 2181c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 218240a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 21839b94acceSBarry Smith 21849665c990SLois Curfman McInnes Options Database Keys: 2185a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 2186a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 2187a6570f20SBarry Smith uses SNESMonitorLGCreate() 2188cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 2189c7afd0dbSLois Curfman McInnes been hardwired into a code by 2190a6570f20SBarry Smith calls to SNESMonitorSet(), but 2191c7afd0dbSLois Curfman McInnes does not cancel those set via 2192c7afd0dbSLois Curfman McInnes the options database. 21939665c990SLois Curfman McInnes 2194639f9d9dSBarry Smith Notes: 21956bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 2196a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 21976bc08f3fSLois Curfman McInnes order in which they were set. 2198639f9d9dSBarry Smith 2199025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 2200025f1a04SBarry Smith 220136851e7fSLois Curfman McInnes Level: intermediate 220236851e7fSLois Curfman McInnes 22039b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 22049b94acceSBarry Smith 2205a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 22069b94acceSBarry Smith @*/ 2207c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 22089b94acceSBarry Smith { 2209b90d0a6eSBarry Smith PetscInt i; 2210649052a6SBarry Smith PetscErrorCode ierr; 2211b90d0a6eSBarry Smith 22123a40ed3dSBarry Smith PetscFunctionBegin; 22130700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 221417186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2215b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 2216649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 2217649052a6SBarry Smith if (monitordestroy) { 2218c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 2219649052a6SBarry Smith } 2220b90d0a6eSBarry Smith PetscFunctionReturn(0); 2221b90d0a6eSBarry Smith } 2222b90d0a6eSBarry Smith } 2223b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 2224b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 2225639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 22263a40ed3dSBarry Smith PetscFunctionReturn(0); 22279b94acceSBarry Smith } 22289b94acceSBarry Smith 22294a2ae208SSatish Balay #undef __FUNCT__ 2230a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 22315cd90555SBarry Smith /*@C 2232a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 22335cd90555SBarry Smith 22343f9fe445SBarry Smith Logically Collective on SNES 2235c7afd0dbSLois Curfman McInnes 22365cd90555SBarry Smith Input Parameters: 22375cd90555SBarry Smith . snes - the SNES context 22385cd90555SBarry Smith 22391a480d89SAdministrator Options Database Key: 2240a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 2241a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 2242c7afd0dbSLois Curfman McInnes set via the options database 22435cd90555SBarry Smith 22445cd90555SBarry Smith Notes: 22455cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 22465cd90555SBarry Smith 224736851e7fSLois Curfman McInnes Level: intermediate 224836851e7fSLois Curfman McInnes 22495cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 22505cd90555SBarry Smith 2251a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 22525cd90555SBarry Smith @*/ 22537087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 22545cd90555SBarry Smith { 2255d952e501SBarry Smith PetscErrorCode ierr; 2256d952e501SBarry Smith PetscInt i; 2257d952e501SBarry Smith 22585cd90555SBarry Smith PetscFunctionBegin; 22590700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2260d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 2261d952e501SBarry Smith if (snes->monitordestroy[i]) { 22623c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 2263d952e501SBarry Smith } 2264d952e501SBarry Smith } 22655cd90555SBarry Smith snes->numbermonitors = 0; 22665cd90555SBarry Smith PetscFunctionReturn(0); 22675cd90555SBarry Smith } 22685cd90555SBarry Smith 22694a2ae208SSatish Balay #undef __FUNCT__ 22704a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 22719b94acceSBarry Smith /*@C 22729b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 22739b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 22749b94acceSBarry Smith 22753f9fe445SBarry Smith Logically Collective on SNES 2276fee21e36SBarry Smith 2277c7afd0dbSLois Curfman McInnes Input Parameters: 2278c7afd0dbSLois Curfman McInnes + snes - the SNES context 2279c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 22807f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 22817f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 22829b94acceSBarry Smith 2283c7afd0dbSLois Curfman McInnes Calling sequence of func: 228406ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 2285c7afd0dbSLois Curfman McInnes 2286c7afd0dbSLois Curfman McInnes + snes - the SNES context 228706ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 2288c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 2289184914b5SBarry Smith . reason - reason for convergence/divergence 2290c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 22914b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 22924b27c08aSLois Curfman McInnes - f - 2-norm of function 22939b94acceSBarry Smith 229436851e7fSLois Curfman McInnes Level: advanced 229536851e7fSLois Curfman McInnes 22969b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 22979b94acceSBarry Smith 229885385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 22999b94acceSBarry Smith @*/ 23007087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 23019b94acceSBarry Smith { 23027f7931b9SBarry Smith PetscErrorCode ierr; 23037f7931b9SBarry Smith 23043a40ed3dSBarry Smith PetscFunctionBegin; 23050700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 230685385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 23077f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 23087f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 23097f7931b9SBarry Smith } 231085385478SLisandro Dalcin snes->ops->converged = func; 23117f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 231285385478SLisandro Dalcin snes->cnvP = cctx; 23133a40ed3dSBarry Smith PetscFunctionReturn(0); 23149b94acceSBarry Smith } 23159b94acceSBarry Smith 23164a2ae208SSatish Balay #undef __FUNCT__ 23174a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 231852baeb72SSatish Balay /*@ 2319184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 2320184914b5SBarry Smith 2321184914b5SBarry Smith Not Collective 2322184914b5SBarry Smith 2323184914b5SBarry Smith Input Parameter: 2324184914b5SBarry Smith . snes - the SNES context 2325184914b5SBarry Smith 2326184914b5SBarry Smith Output Parameter: 23274d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 2328184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 2329184914b5SBarry Smith 2330184914b5SBarry Smith Level: intermediate 2331184914b5SBarry Smith 2332184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 2333184914b5SBarry Smith 2334184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 2335184914b5SBarry Smith 233685385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 2337184914b5SBarry Smith @*/ 23387087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 2339184914b5SBarry Smith { 2340184914b5SBarry Smith PetscFunctionBegin; 23410700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23424482741eSBarry Smith PetscValidPointer(reason,2); 2343184914b5SBarry Smith *reason = snes->reason; 2344184914b5SBarry Smith PetscFunctionReturn(0); 2345184914b5SBarry Smith } 2346184914b5SBarry Smith 23474a2ae208SSatish Balay #undef __FUNCT__ 23484a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 2349c9005455SLois Curfman McInnes /*@ 2350c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 2351c9005455SLois Curfman McInnes 23523f9fe445SBarry Smith Logically Collective on SNES 2353fee21e36SBarry Smith 2354c7afd0dbSLois Curfman McInnes Input Parameters: 2355c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 23568c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 2357cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 2358758f92a0SBarry Smith . na - size of a and its 235964731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 2360758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 2361c7afd0dbSLois Curfman McInnes 2362308dcc3eSBarry Smith Notes: 2363308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 2364308dcc3eSBarry Smith default array of length 10000 is allocated. 2365308dcc3eSBarry Smith 2366c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 2367c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 2368c9005455SLois Curfman McInnes during the section of code that is being timed. 2369c9005455SLois Curfman McInnes 237036851e7fSLois Curfman McInnes Level: intermediate 237136851e7fSLois Curfman McInnes 2372c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 2373758f92a0SBarry Smith 237408405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 2375758f92a0SBarry Smith 2376c9005455SLois Curfman McInnes @*/ 23777087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 2378c9005455SLois Curfman McInnes { 2379308dcc3eSBarry Smith PetscErrorCode ierr; 2380308dcc3eSBarry Smith 23813a40ed3dSBarry Smith PetscFunctionBegin; 23820700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23834482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 2384a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 2385308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 2386308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 2387308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 2388308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 2389308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 2390308dcc3eSBarry Smith } 2391c9005455SLois Curfman McInnes snes->conv_hist = a; 2392758f92a0SBarry Smith snes->conv_hist_its = its; 2393758f92a0SBarry Smith snes->conv_hist_max = na; 2394a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 2395758f92a0SBarry Smith snes->conv_hist_reset = reset; 2396758f92a0SBarry Smith PetscFunctionReturn(0); 2397758f92a0SBarry Smith } 2398758f92a0SBarry Smith 2399308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 2400c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 2401c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 2402308dcc3eSBarry Smith EXTERN_C_BEGIN 2403308dcc3eSBarry Smith #undef __FUNCT__ 2404308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 2405308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 2406308dcc3eSBarry Smith { 2407308dcc3eSBarry Smith mxArray *mat; 2408308dcc3eSBarry Smith PetscInt i; 2409308dcc3eSBarry Smith PetscReal *ar; 2410308dcc3eSBarry Smith 2411308dcc3eSBarry Smith PetscFunctionBegin; 2412308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 2413308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 2414308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 2415308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 2416308dcc3eSBarry Smith } 2417308dcc3eSBarry Smith PetscFunctionReturn(mat); 2418308dcc3eSBarry Smith } 2419308dcc3eSBarry Smith EXTERN_C_END 2420308dcc3eSBarry Smith #endif 2421308dcc3eSBarry Smith 2422308dcc3eSBarry Smith 24234a2ae208SSatish Balay #undef __FUNCT__ 24244a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 24250c4c9dddSBarry Smith /*@C 2426758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 2427758f92a0SBarry Smith 24283f9fe445SBarry Smith Not Collective 2429758f92a0SBarry Smith 2430758f92a0SBarry Smith Input Parameter: 2431758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 2432758f92a0SBarry Smith 2433758f92a0SBarry Smith Output Parameters: 2434758f92a0SBarry Smith . a - array to hold history 2435758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 2436758f92a0SBarry Smith negative if not converged) for each solve. 2437758f92a0SBarry Smith - na - size of a and its 2438758f92a0SBarry Smith 2439758f92a0SBarry Smith Notes: 2440758f92a0SBarry Smith The calling sequence for this routine in Fortran is 2441758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 2442758f92a0SBarry Smith 2443758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 2444758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 2445758f92a0SBarry Smith during the section of code that is being timed. 2446758f92a0SBarry Smith 2447758f92a0SBarry Smith Level: intermediate 2448758f92a0SBarry Smith 2449758f92a0SBarry Smith .keywords: SNES, get, convergence, history 2450758f92a0SBarry Smith 2451758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 2452758f92a0SBarry Smith 2453758f92a0SBarry Smith @*/ 24547087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 2455758f92a0SBarry Smith { 2456758f92a0SBarry Smith PetscFunctionBegin; 24570700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2458758f92a0SBarry Smith if (a) *a = snes->conv_hist; 2459758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 2460758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 24613a40ed3dSBarry Smith PetscFunctionReturn(0); 2462c9005455SLois Curfman McInnes } 2463c9005455SLois Curfman McInnes 2464e74ef692SMatthew Knepley #undef __FUNCT__ 2465e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 2466ac226902SBarry Smith /*@C 246776b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 2468eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 24697e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 247076b2cf59SMatthew Knepley 24713f9fe445SBarry Smith Logically Collective on SNES 247276b2cf59SMatthew Knepley 247376b2cf59SMatthew Knepley Input Parameters: 247476b2cf59SMatthew Knepley . snes - The nonlinear solver context 247576b2cf59SMatthew Knepley . func - The function 247676b2cf59SMatthew Knepley 247776b2cf59SMatthew Knepley Calling sequence of func: 2478b5d30489SBarry Smith . func (SNES snes, PetscInt step); 247976b2cf59SMatthew Knepley 248076b2cf59SMatthew Knepley . step - The current step of the iteration 248176b2cf59SMatthew Knepley 2482fe97e370SBarry Smith Level: advanced 2483fe97e370SBarry Smith 2484fe97e370SBarry 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() 2485fe97e370SBarry Smith This is not used by most users. 248676b2cf59SMatthew Knepley 248776b2cf59SMatthew Knepley .keywords: SNES, update 2488b5d30489SBarry Smith 248985385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 249076b2cf59SMatthew Knepley @*/ 24917087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 249276b2cf59SMatthew Knepley { 249376b2cf59SMatthew Knepley PetscFunctionBegin; 24940700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 2495e7788613SBarry Smith snes->ops->update = func; 249676b2cf59SMatthew Knepley PetscFunctionReturn(0); 249776b2cf59SMatthew Knepley } 249876b2cf59SMatthew Knepley 2499e74ef692SMatthew Knepley #undef __FUNCT__ 2500e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 250176b2cf59SMatthew Knepley /*@ 250276b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 250376b2cf59SMatthew Knepley 250476b2cf59SMatthew Knepley Not collective 250576b2cf59SMatthew Knepley 250676b2cf59SMatthew Knepley Input Parameters: 250776b2cf59SMatthew Knepley . snes - The nonlinear solver context 250876b2cf59SMatthew Knepley . step - The current step of the iteration 250976b2cf59SMatthew Knepley 2510205452f4SMatthew Knepley Level: intermediate 2511205452f4SMatthew Knepley 251276b2cf59SMatthew Knepley .keywords: SNES, update 2513a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 251476b2cf59SMatthew Knepley @*/ 25157087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 251676b2cf59SMatthew Knepley { 251776b2cf59SMatthew Knepley PetscFunctionBegin; 251876b2cf59SMatthew Knepley PetscFunctionReturn(0); 251976b2cf59SMatthew Knepley } 252076b2cf59SMatthew Knepley 25214a2ae208SSatish Balay #undef __FUNCT__ 25224a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 25239b94acceSBarry Smith /* 25249b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 25259b94acceSBarry Smith positive parameter delta. 25269b94acceSBarry Smith 25279b94acceSBarry Smith Input Parameters: 2528c7afd0dbSLois Curfman McInnes + snes - the SNES context 25299b94acceSBarry Smith . y - approximate solution of linear system 25309b94acceSBarry Smith . fnorm - 2-norm of current function 2531c7afd0dbSLois Curfman McInnes - delta - trust region size 25329b94acceSBarry Smith 25339b94acceSBarry Smith Output Parameters: 2534c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 25359b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 25369b94acceSBarry Smith region, and exceeds zero otherwise. 2537c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 25389b94acceSBarry Smith 25399b94acceSBarry Smith Note: 25404b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 25419b94acceSBarry Smith is set to be the maximum allowable step size. 25429b94acceSBarry Smith 25439b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 25449b94acceSBarry Smith */ 2545dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 25469b94acceSBarry Smith { 2547064f8208SBarry Smith PetscReal nrm; 2548ea709b57SSatish Balay PetscScalar cnorm; 2549dfbe8321SBarry Smith PetscErrorCode ierr; 25503a40ed3dSBarry Smith 25513a40ed3dSBarry Smith PetscFunctionBegin; 25520700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 25530700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 2554c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 2555184914b5SBarry Smith 2556064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 2557064f8208SBarry Smith if (nrm > *delta) { 2558064f8208SBarry Smith nrm = *delta/nrm; 2559064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 2560064f8208SBarry Smith cnorm = nrm; 25612dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 25629b94acceSBarry Smith *ynorm = *delta; 25639b94acceSBarry Smith } else { 25649b94acceSBarry Smith *gpnorm = 0.0; 2565064f8208SBarry Smith *ynorm = nrm; 25669b94acceSBarry Smith } 25673a40ed3dSBarry Smith PetscFunctionReturn(0); 25689b94acceSBarry Smith } 25699b94acceSBarry Smith 25704a2ae208SSatish Balay #undef __FUNCT__ 25714a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 25726ce558aeSBarry Smith /*@C 2573f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 2574f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 25759b94acceSBarry Smith 2576c7afd0dbSLois Curfman McInnes Collective on SNES 2577c7afd0dbSLois Curfman McInnes 2578b2002411SLois Curfman McInnes Input Parameters: 2579c7afd0dbSLois Curfman McInnes + snes - the SNES context 2580f69a0ea3SMatthew Knepley . b - the constant part of the equation, or PETSC_NULL to use zero. 258185385478SLisandro Dalcin - x - the solution vector. 25829b94acceSBarry Smith 2583b2002411SLois Curfman McInnes Notes: 25848ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 25858ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 25868ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 25878ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 25888ddd3da0SLois Curfman McInnes 258936851e7fSLois Curfman McInnes Level: beginner 259036851e7fSLois Curfman McInnes 25919b94acceSBarry Smith .keywords: SNES, nonlinear, solve 25929b94acceSBarry Smith 259385385478SLisandro Dalcin .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian() 25949b94acceSBarry Smith @*/ 25957087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 25969b94acceSBarry Smith { 2597dfbe8321SBarry Smith PetscErrorCode ierr; 2598ace3abfcSBarry Smith PetscBool flg; 2599eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 2600eabae89aSBarry Smith PetscViewer viewer; 2601efd51863SBarry Smith PetscInt grid; 2602052efed2SBarry Smith 26033a40ed3dSBarry Smith PetscFunctionBegin; 26040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 26050700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,3); 2606f69a0ea3SMatthew Knepley PetscCheckSameComm(snes,1,x,3); 26070700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 260885385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 260985385478SLisandro Dalcin 2610a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 2611efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 2612efd51863SBarry Smith 261385385478SLisandro Dalcin /* set solution vector */ 2614efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 26156bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 261685385478SLisandro Dalcin snes->vec_sol = x; 261785385478SLisandro Dalcin /* set afine vector if provided */ 261885385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 26196bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 262085385478SLisandro Dalcin snes->vec_rhs = b; 262185385478SLisandro Dalcin 262270e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 26233f149594SLisandro Dalcin 2624d25893d9SBarry Smith if (!grid && snes->ops->computeinitialguess) { 2625d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 2626d25893d9SBarry Smith } 2627d25893d9SBarry Smith 2628abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 262950ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 2630d5e45103SBarry Smith 26313f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 26324936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 263385385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 26344936397dSBarry Smith if (snes->domainerror){ 26354936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 26364936397dSBarry Smith snes->domainerror = PETSC_FALSE; 26374936397dSBarry Smith } 263817186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 26393f149594SLisandro Dalcin 26407adad957SLisandro Dalcin ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 2641eabae89aSBarry Smith if (flg && !PetscPreLoadingOn) { 26427adad957SLisandro Dalcin ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 2643eabae89aSBarry Smith ierr = SNESView(snes,viewer);CHKERRQ(ierr); 26446bf464f9SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 2645eabae89aSBarry Smith } 2646eabae89aSBarry Smith 264790d69ab7SBarry Smith flg = PETSC_FALSE; 2648acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 2649da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 26505968eb51SBarry Smith if (snes->printreason) { 2651a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 26525968eb51SBarry Smith if (snes->reason > 0) { 2653a8248277SBarry Smith ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 26545968eb51SBarry Smith } else { 2655a8248277SBarry Smith ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 26565968eb51SBarry Smith } 2657a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 26585968eb51SBarry Smith } 26595968eb51SBarry Smith 2660e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 2661efd51863SBarry Smith if (grid < snes->gridsequence) { 2662efd51863SBarry Smith DM fine; 2663efd51863SBarry Smith Vec xnew; 2664efd51863SBarry Smith Mat interp; 2665efd51863SBarry Smith 2666efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 2667efd51863SBarry Smith ierr = DMGetInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 2668efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 2669efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 2670efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 2671efd51863SBarry Smith x = xnew; 2672efd51863SBarry Smith 2673efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 2674efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 2675efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 2676a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 2677efd51863SBarry Smith } 2678efd51863SBarry Smith } 26793a40ed3dSBarry Smith PetscFunctionReturn(0); 26809b94acceSBarry Smith } 26819b94acceSBarry Smith 26829b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 26839b94acceSBarry Smith 26844a2ae208SSatish Balay #undef __FUNCT__ 26854a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 268682bf6240SBarry Smith /*@C 26874b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 26889b94acceSBarry Smith 2689fee21e36SBarry Smith Collective on SNES 2690fee21e36SBarry Smith 2691c7afd0dbSLois Curfman McInnes Input Parameters: 2692c7afd0dbSLois Curfman McInnes + snes - the SNES context 2693454a90a3SBarry Smith - type - a known method 2694c7afd0dbSLois Curfman McInnes 2695c7afd0dbSLois Curfman McInnes Options Database Key: 2696454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 2697c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 2698ae12b187SLois Curfman McInnes 26999b94acceSBarry Smith Notes: 2700e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 27014b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 2702c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 27034b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 2704c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 27059b94acceSBarry Smith 2706ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 2707ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 2708ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 2709ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 2710ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 2711ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 2712ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 2713ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 2714ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 2715b0a32e0cSBarry Smith appropriate method. 271636851e7fSLois Curfman McInnes 271736851e7fSLois Curfman McInnes Level: intermediate 2718a703fe33SLois Curfman McInnes 2719454a90a3SBarry Smith .keywords: SNES, set, type 2720435da068SBarry Smith 2721435da068SBarry Smith .seealso: SNESType, SNESCreate() 2722435da068SBarry Smith 27239b94acceSBarry Smith @*/ 27247087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 27259b94acceSBarry Smith { 2726dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 2727ace3abfcSBarry Smith PetscBool match; 27283a40ed3dSBarry Smith 27293a40ed3dSBarry Smith PetscFunctionBegin; 27300700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 27314482741eSBarry Smith PetscValidCharPointer(type,2); 273282bf6240SBarry Smith 27336831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 27340f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 273592ff6ae8SBarry Smith 27364b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 2737e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 273875396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 273975396ef9SLisandro Dalcin if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); } 274075396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 274175396ef9SLisandro Dalcin snes->ops->setup = 0; 274275396ef9SLisandro Dalcin snes->ops->solve = 0; 274375396ef9SLisandro Dalcin snes->ops->view = 0; 274475396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 274575396ef9SLisandro Dalcin snes->ops->destroy = 0; 274675396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 274775396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 2748454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 274903bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 27509fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 27519fb22e1aSBarry Smith if (PetscAMSPublishAll) { 27529fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 27539fb22e1aSBarry Smith } 27549fb22e1aSBarry Smith #endif 27553a40ed3dSBarry Smith PetscFunctionReturn(0); 27569b94acceSBarry Smith } 27579b94acceSBarry Smith 2758a847f771SSatish Balay 27599b94acceSBarry Smith /* --------------------------------------------------------------------- */ 27604a2ae208SSatish Balay #undef __FUNCT__ 27614a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 276252baeb72SSatish Balay /*@ 27639b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 2764f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 27659b94acceSBarry Smith 2766fee21e36SBarry Smith Not Collective 2767fee21e36SBarry Smith 276836851e7fSLois Curfman McInnes Level: advanced 276936851e7fSLois Curfman McInnes 27709b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 27719b94acceSBarry Smith 27729b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 27739b94acceSBarry Smith @*/ 27747087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 27759b94acceSBarry Smith { 2776dfbe8321SBarry Smith PetscErrorCode ierr; 277782bf6240SBarry Smith 27783a40ed3dSBarry Smith PetscFunctionBegin; 27791441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 27804c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 27813a40ed3dSBarry Smith PetscFunctionReturn(0); 27829b94acceSBarry Smith } 27839b94acceSBarry Smith 27844a2ae208SSatish Balay #undef __FUNCT__ 27854a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 27869b94acceSBarry Smith /*@C 27879a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 27889b94acceSBarry Smith 2789c7afd0dbSLois Curfman McInnes Not Collective 2790c7afd0dbSLois Curfman McInnes 27919b94acceSBarry Smith Input Parameter: 27924b0e389bSBarry Smith . snes - nonlinear solver context 27939b94acceSBarry Smith 27949b94acceSBarry Smith Output Parameter: 27953a7fca6bSBarry Smith . type - SNES method (a character string) 27969b94acceSBarry Smith 279736851e7fSLois Curfman McInnes Level: intermediate 279836851e7fSLois Curfman McInnes 2799454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 28009b94acceSBarry Smith @*/ 28017087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 28029b94acceSBarry Smith { 28033a40ed3dSBarry Smith PetscFunctionBegin; 28040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 28054482741eSBarry Smith PetscValidPointer(type,2); 28067adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 28073a40ed3dSBarry Smith PetscFunctionReturn(0); 28089b94acceSBarry Smith } 28099b94acceSBarry Smith 28104a2ae208SSatish Balay #undef __FUNCT__ 28114a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 281252baeb72SSatish Balay /*@ 28139b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 28149b94acceSBarry Smith stored. 28159b94acceSBarry Smith 2816c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 2817c7afd0dbSLois Curfman McInnes 28189b94acceSBarry Smith Input Parameter: 28199b94acceSBarry Smith . snes - the SNES context 28209b94acceSBarry Smith 28219b94acceSBarry Smith Output Parameter: 28229b94acceSBarry Smith . x - the solution 28239b94acceSBarry Smith 282470e92668SMatthew Knepley Level: intermediate 282536851e7fSLois Curfman McInnes 28269b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 28279b94acceSBarry Smith 282885385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 28299b94acceSBarry Smith @*/ 28307087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 28319b94acceSBarry Smith { 28323a40ed3dSBarry Smith PetscFunctionBegin; 28330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 28344482741eSBarry Smith PetscValidPointer(x,2); 283585385478SLisandro Dalcin *x = snes->vec_sol; 283670e92668SMatthew Knepley PetscFunctionReturn(0); 283770e92668SMatthew Knepley } 283870e92668SMatthew Knepley 283970e92668SMatthew Knepley #undef __FUNCT__ 28404a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 284152baeb72SSatish Balay /*@ 28429b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 28439b94acceSBarry Smith stored. 28449b94acceSBarry Smith 2845c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 2846c7afd0dbSLois Curfman McInnes 28479b94acceSBarry Smith Input Parameter: 28489b94acceSBarry Smith . snes - the SNES context 28499b94acceSBarry Smith 28509b94acceSBarry Smith Output Parameter: 28519b94acceSBarry Smith . x - the solution update 28529b94acceSBarry Smith 285336851e7fSLois Curfman McInnes Level: advanced 285436851e7fSLois Curfman McInnes 28559b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 28569b94acceSBarry Smith 285785385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 28589b94acceSBarry Smith @*/ 28597087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 28609b94acceSBarry Smith { 28613a40ed3dSBarry Smith PetscFunctionBegin; 28620700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 28634482741eSBarry Smith PetscValidPointer(x,2); 286485385478SLisandro Dalcin *x = snes->vec_sol_update; 28653a40ed3dSBarry Smith PetscFunctionReturn(0); 28669b94acceSBarry Smith } 28679b94acceSBarry Smith 28684a2ae208SSatish Balay #undef __FUNCT__ 28694a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 28709b94acceSBarry Smith /*@C 28713638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 28729b94acceSBarry Smith 2873c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 2874c7afd0dbSLois Curfman McInnes 28759b94acceSBarry Smith Input Parameter: 28769b94acceSBarry Smith . snes - the SNES context 28779b94acceSBarry Smith 28789b94acceSBarry Smith Output Parameter: 28797bf4e008SBarry Smith + r - the function (or PETSC_NULL) 288070e92668SMatthew Knepley . func - the function (or PETSC_NULL) 288170e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 28829b94acceSBarry Smith 288336851e7fSLois Curfman McInnes Level: advanced 288436851e7fSLois Curfman McInnes 2885a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 28869b94acceSBarry Smith 28874b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 28889b94acceSBarry Smith @*/ 28897087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 28909b94acceSBarry Smith { 28913a40ed3dSBarry Smith PetscFunctionBegin; 28920700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 289385385478SLisandro Dalcin if (r) *r = snes->vec_func; 2894e7788613SBarry Smith if (func) *func = snes->ops->computefunction; 289570e92668SMatthew Knepley if (ctx) *ctx = snes->funP; 28963a40ed3dSBarry Smith PetscFunctionReturn(0); 28979b94acceSBarry Smith } 28989b94acceSBarry Smith 28994a2ae208SSatish Balay #undef __FUNCT__ 29004a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 29013c7409f5SSatish Balay /*@C 29023c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 2903d850072dSLois Curfman McInnes SNES options in the database. 29043c7409f5SSatish Balay 29053f9fe445SBarry Smith Logically Collective on SNES 2906fee21e36SBarry Smith 2907c7afd0dbSLois Curfman McInnes Input Parameter: 2908c7afd0dbSLois Curfman McInnes + snes - the SNES context 2909c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 2910c7afd0dbSLois Curfman McInnes 2911d850072dSLois Curfman McInnes Notes: 2912a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 2913c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 2914d850072dSLois Curfman McInnes 291536851e7fSLois Curfman McInnes Level: advanced 291636851e7fSLois Curfman McInnes 29173c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 2918a86d99e1SLois Curfman McInnes 2919a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 29203c7409f5SSatish Balay @*/ 29217087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 29223c7409f5SSatish Balay { 2923dfbe8321SBarry Smith PetscErrorCode ierr; 29243c7409f5SSatish Balay 29253a40ed3dSBarry Smith PetscFunctionBegin; 29260700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2927639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 29281cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 292994b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 29303a40ed3dSBarry Smith PetscFunctionReturn(0); 29313c7409f5SSatish Balay } 29323c7409f5SSatish Balay 29334a2ae208SSatish Balay #undef __FUNCT__ 29344a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 29353c7409f5SSatish Balay /*@C 2936f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 2937d850072dSLois Curfman McInnes SNES options in the database. 29383c7409f5SSatish Balay 29393f9fe445SBarry Smith Logically Collective on SNES 2940fee21e36SBarry Smith 2941c7afd0dbSLois Curfman McInnes Input Parameters: 2942c7afd0dbSLois Curfman McInnes + snes - the SNES context 2943c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 2944c7afd0dbSLois Curfman McInnes 2945d850072dSLois Curfman McInnes Notes: 2946a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 2947c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 2948d850072dSLois Curfman McInnes 294936851e7fSLois Curfman McInnes Level: advanced 295036851e7fSLois Curfman McInnes 29513c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 2952a86d99e1SLois Curfman McInnes 2953a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 29543c7409f5SSatish Balay @*/ 29557087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 29563c7409f5SSatish Balay { 2957dfbe8321SBarry Smith PetscErrorCode ierr; 29583c7409f5SSatish Balay 29593a40ed3dSBarry Smith PetscFunctionBegin; 29600700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2961639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 29621cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 296394b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 29643a40ed3dSBarry Smith PetscFunctionReturn(0); 29653c7409f5SSatish Balay } 29663c7409f5SSatish Balay 29674a2ae208SSatish Balay #undef __FUNCT__ 29684a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 29699ab63eb5SSatish Balay /*@C 29703c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 29713c7409f5SSatish Balay SNES options in the database. 29723c7409f5SSatish Balay 2973c7afd0dbSLois Curfman McInnes Not Collective 2974c7afd0dbSLois Curfman McInnes 29753c7409f5SSatish Balay Input Parameter: 29763c7409f5SSatish Balay . snes - the SNES context 29773c7409f5SSatish Balay 29783c7409f5SSatish Balay Output Parameter: 29793c7409f5SSatish Balay . prefix - pointer to the prefix string used 29803c7409f5SSatish Balay 29814ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 29829ab63eb5SSatish Balay sufficient length to hold the prefix. 29839ab63eb5SSatish Balay 298436851e7fSLois Curfman McInnes Level: advanced 298536851e7fSLois Curfman McInnes 29863c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 2987a86d99e1SLois Curfman McInnes 2988a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 29893c7409f5SSatish Balay @*/ 29907087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 29913c7409f5SSatish Balay { 2992dfbe8321SBarry Smith PetscErrorCode ierr; 29933c7409f5SSatish Balay 29943a40ed3dSBarry Smith PetscFunctionBegin; 29950700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2996639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 29973a40ed3dSBarry Smith PetscFunctionReturn(0); 29983c7409f5SSatish Balay } 29993c7409f5SSatish Balay 3000b2002411SLois Curfman McInnes 30014a2ae208SSatish Balay #undef __FUNCT__ 30024a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 30033cea93caSBarry Smith /*@C 30043cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 30053cea93caSBarry Smith 30067f6c08e0SMatthew Knepley Level: advanced 30073cea93caSBarry Smith @*/ 30087087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3009b2002411SLois Curfman McInnes { 3010e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3011dfbe8321SBarry Smith PetscErrorCode ierr; 3012b2002411SLois Curfman McInnes 3013b2002411SLois Curfman McInnes PetscFunctionBegin; 3014b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3015c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3016b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3017b2002411SLois Curfman McInnes } 3018da9b6338SBarry Smith 3019da9b6338SBarry Smith #undef __FUNCT__ 3020da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 30217087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3022da9b6338SBarry Smith { 3023dfbe8321SBarry Smith PetscErrorCode ierr; 302477431f27SBarry Smith PetscInt N,i,j; 3025da9b6338SBarry Smith Vec u,uh,fh; 3026da9b6338SBarry Smith PetscScalar value; 3027da9b6338SBarry Smith PetscReal norm; 3028da9b6338SBarry Smith 3029da9b6338SBarry Smith PetscFunctionBegin; 3030da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3031da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3032da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3033da9b6338SBarry Smith 3034da9b6338SBarry Smith /* currently only works for sequential */ 3035da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3036da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3037da9b6338SBarry Smith for (i=0; i<N; i++) { 3038da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 303977431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3040da9b6338SBarry Smith for (j=-10; j<11; j++) { 3041ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3042da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 30433ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3044da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 304577431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3046da9b6338SBarry Smith value = -value; 3047da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3048da9b6338SBarry Smith } 3049da9b6338SBarry Smith } 30506bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 30516bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 3052da9b6338SBarry Smith PetscFunctionReturn(0); 3053da9b6338SBarry Smith } 305471f87433Sdalcinl 305571f87433Sdalcinl #undef __FUNCT__ 3056fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 305771f87433Sdalcinl /*@ 3058fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 305971f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 306071f87433Sdalcinl Newton method. 306171f87433Sdalcinl 30623f9fe445SBarry Smith Logically Collective on SNES 306371f87433Sdalcinl 306471f87433Sdalcinl Input Parameters: 306571f87433Sdalcinl + snes - SNES context 306671f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 306771f87433Sdalcinl 306864ba62caSBarry Smith Options Database: 306964ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 307064ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 307164ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 307264ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 307364ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 307464ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 307564ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 307664ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 307764ba62caSBarry Smith 307871f87433Sdalcinl Notes: 307971f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 308071f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 308171f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 308271f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 308371f87433Sdalcinl solver. 308471f87433Sdalcinl 308571f87433Sdalcinl Level: advanced 308671f87433Sdalcinl 308771f87433Sdalcinl Reference: 308871f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 308971f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 309071f87433Sdalcinl 309171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 309271f87433Sdalcinl 3093fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 309471f87433Sdalcinl @*/ 30957087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 309671f87433Sdalcinl { 309771f87433Sdalcinl PetscFunctionBegin; 30980700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3099acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 310071f87433Sdalcinl snes->ksp_ewconv = flag; 310171f87433Sdalcinl PetscFunctionReturn(0); 310271f87433Sdalcinl } 310371f87433Sdalcinl 310471f87433Sdalcinl #undef __FUNCT__ 3105fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 310671f87433Sdalcinl /*@ 3107fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 310871f87433Sdalcinl for computing relative tolerance for linear solvers within an 310971f87433Sdalcinl inexact Newton method. 311071f87433Sdalcinl 311171f87433Sdalcinl Not Collective 311271f87433Sdalcinl 311371f87433Sdalcinl Input Parameter: 311471f87433Sdalcinl . snes - SNES context 311571f87433Sdalcinl 311671f87433Sdalcinl Output Parameter: 311771f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 311871f87433Sdalcinl 311971f87433Sdalcinl Notes: 312071f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 312171f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 312271f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 312371f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 312471f87433Sdalcinl solver. 312571f87433Sdalcinl 312671f87433Sdalcinl Level: advanced 312771f87433Sdalcinl 312871f87433Sdalcinl Reference: 312971f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 313071f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 313171f87433Sdalcinl 313271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 313371f87433Sdalcinl 3134fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 313571f87433Sdalcinl @*/ 31367087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 313771f87433Sdalcinl { 313871f87433Sdalcinl PetscFunctionBegin; 31390700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 314071f87433Sdalcinl PetscValidPointer(flag,2); 314171f87433Sdalcinl *flag = snes->ksp_ewconv; 314271f87433Sdalcinl PetscFunctionReturn(0); 314371f87433Sdalcinl } 314471f87433Sdalcinl 314571f87433Sdalcinl #undef __FUNCT__ 3146fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 314771f87433Sdalcinl /*@ 3148fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 314971f87433Sdalcinl convergence criteria for the linear solvers within an inexact 315071f87433Sdalcinl Newton method. 315171f87433Sdalcinl 31523f9fe445SBarry Smith Logically Collective on SNES 315371f87433Sdalcinl 315471f87433Sdalcinl Input Parameters: 315571f87433Sdalcinl + snes - SNES context 315671f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 315771f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 315871f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 315971f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 316071f87433Sdalcinl (0 <= gamma2 <= 1) 316171f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 316271f87433Sdalcinl . alpha2 - power for safeguard 316371f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 316471f87433Sdalcinl 316571f87433Sdalcinl Note: 316671f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 316771f87433Sdalcinl 316871f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 316971f87433Sdalcinl 317071f87433Sdalcinl Level: advanced 317171f87433Sdalcinl 317271f87433Sdalcinl Reference: 317371f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 317471f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 317571f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 317671f87433Sdalcinl 317771f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 317871f87433Sdalcinl 3179fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 318071f87433Sdalcinl @*/ 31817087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 318271f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 318371f87433Sdalcinl { 3184fa9f3622SBarry Smith SNESKSPEW *kctx; 318571f87433Sdalcinl PetscFunctionBegin; 31860700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3187fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3188e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 3189c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 3190c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 3191c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 3192c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 3193c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 3194c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 3195c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 319671f87433Sdalcinl 319771f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 319871f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 319971f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 320071f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 320171f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 320271f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 320371f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 320471f87433Sdalcinl 320571f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 3206e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 320771f87433Sdalcinl } 320871f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 3209e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 321071f87433Sdalcinl } 321171f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 3212e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 321371f87433Sdalcinl } 321471f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 3215e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 321671f87433Sdalcinl } 321771f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 3218e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 321971f87433Sdalcinl } 322071f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 3221e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 322271f87433Sdalcinl } 322371f87433Sdalcinl PetscFunctionReturn(0); 322471f87433Sdalcinl } 322571f87433Sdalcinl 322671f87433Sdalcinl #undef __FUNCT__ 3227fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 322871f87433Sdalcinl /*@ 3229fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 323071f87433Sdalcinl convergence criteria for the linear solvers within an inexact 323171f87433Sdalcinl Newton method. 323271f87433Sdalcinl 323371f87433Sdalcinl Not Collective 323471f87433Sdalcinl 323571f87433Sdalcinl Input Parameters: 323671f87433Sdalcinl snes - SNES context 323771f87433Sdalcinl 323871f87433Sdalcinl Output Parameters: 323971f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 324071f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 324171f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 324271f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 324371f87433Sdalcinl (0 <= gamma2 <= 1) 324471f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 324571f87433Sdalcinl . alpha2 - power for safeguard 324671f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 324771f87433Sdalcinl 324871f87433Sdalcinl Level: advanced 324971f87433Sdalcinl 325071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 325171f87433Sdalcinl 3252fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 325371f87433Sdalcinl @*/ 32547087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 325571f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 325671f87433Sdalcinl { 3257fa9f3622SBarry Smith SNESKSPEW *kctx; 325871f87433Sdalcinl PetscFunctionBegin; 32590700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3260fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3261e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 326271f87433Sdalcinl if(version) *version = kctx->version; 326371f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 326471f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 326571f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 326671f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 326771f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 326871f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 326971f87433Sdalcinl PetscFunctionReturn(0); 327071f87433Sdalcinl } 327171f87433Sdalcinl 327271f87433Sdalcinl #undef __FUNCT__ 3273fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 3274fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 327571f87433Sdalcinl { 327671f87433Sdalcinl PetscErrorCode ierr; 3277fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 327871f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 327971f87433Sdalcinl 328071f87433Sdalcinl PetscFunctionBegin; 3281e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 328271f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 328371f87433Sdalcinl rtol = kctx->rtol_0; 328471f87433Sdalcinl } else { 328571f87433Sdalcinl if (kctx->version == 1) { 328671f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 328771f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 328871f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 328971f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 329071f87433Sdalcinl } else if (kctx->version == 2) { 329171f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 329271f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 329371f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 329471f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 329571f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 329671f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 329771f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 329871f87433Sdalcinl stol = PetscMax(rtol,stol); 329971f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 330071f87433Sdalcinl /* safeguard: avoid oversolving */ 330171f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 330271f87433Sdalcinl stol = PetscMax(rtol,stol); 330371f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 3304e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 330571f87433Sdalcinl } 330671f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 330771f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 330871f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 330971f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 331071f87433Sdalcinl PetscFunctionReturn(0); 331171f87433Sdalcinl } 331271f87433Sdalcinl 331371f87433Sdalcinl #undef __FUNCT__ 3314fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 3315fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 331671f87433Sdalcinl { 331771f87433Sdalcinl PetscErrorCode ierr; 3318fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 331971f87433Sdalcinl PCSide pcside; 332071f87433Sdalcinl Vec lres; 332171f87433Sdalcinl 332271f87433Sdalcinl PetscFunctionBegin; 3323e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 332471f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 332571f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 332671f87433Sdalcinl if (kctx->version == 1) { 3327b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 332871f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 332971f87433Sdalcinl /* KSP residual is true linear residual */ 333071f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 333171f87433Sdalcinl } else { 333271f87433Sdalcinl /* KSP residual is preconditioned residual */ 333371f87433Sdalcinl /* compute true linear residual norm */ 333471f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 333571f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 333671f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 333771f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 33386bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 333971f87433Sdalcinl } 334071f87433Sdalcinl } 334171f87433Sdalcinl PetscFunctionReturn(0); 334271f87433Sdalcinl } 334371f87433Sdalcinl 334471f87433Sdalcinl #undef __FUNCT__ 334571f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 334671f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 334771f87433Sdalcinl { 334871f87433Sdalcinl PetscErrorCode ierr; 334971f87433Sdalcinl 335071f87433Sdalcinl PetscFunctionBegin; 3351fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 335271f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 3353fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 335471f87433Sdalcinl PetscFunctionReturn(0); 335571f87433Sdalcinl } 33566c699258SBarry Smith 33576c699258SBarry Smith #undef __FUNCT__ 33586c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 33596c699258SBarry Smith /*@ 33606c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 33616c699258SBarry Smith 33623f9fe445SBarry Smith Logically Collective on SNES 33636c699258SBarry Smith 33646c699258SBarry Smith Input Parameters: 33656c699258SBarry Smith + snes - the preconditioner context 33666c699258SBarry Smith - dm - the dm 33676c699258SBarry Smith 33686c699258SBarry Smith Level: intermediate 33696c699258SBarry Smith 33706c699258SBarry Smith 33716c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 33726c699258SBarry Smith @*/ 33737087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 33746c699258SBarry Smith { 33756c699258SBarry Smith PetscErrorCode ierr; 3376345fed2cSBarry Smith KSP ksp; 33776c699258SBarry Smith 33786c699258SBarry Smith PetscFunctionBegin; 33790700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3380d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 33816bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 33826c699258SBarry Smith snes->dm = dm; 3383345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 3384345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 3385f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 33866c699258SBarry Smith PetscFunctionReturn(0); 33876c699258SBarry Smith } 33886c699258SBarry Smith 33896c699258SBarry Smith #undef __FUNCT__ 33906c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 33916c699258SBarry Smith /*@ 33926c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 33936c699258SBarry Smith 33943f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 33956c699258SBarry Smith 33966c699258SBarry Smith Input Parameter: 33976c699258SBarry Smith . snes - the preconditioner context 33986c699258SBarry Smith 33996c699258SBarry Smith Output Parameter: 34006c699258SBarry Smith . dm - the dm 34016c699258SBarry Smith 34026c699258SBarry Smith Level: intermediate 34036c699258SBarry Smith 34046c699258SBarry Smith 34056c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 34066c699258SBarry Smith @*/ 34077087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 34086c699258SBarry Smith { 34096c699258SBarry Smith PetscFunctionBegin; 34100700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34116c699258SBarry Smith *dm = snes->dm; 34126c699258SBarry Smith PetscFunctionReturn(0); 34136c699258SBarry Smith } 34140807856dSBarry Smith 341531823bd8SMatthew G Knepley #undef __FUNCT__ 341631823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 341731823bd8SMatthew G Knepley /*@ 341831823bd8SMatthew G Knepley SNESSetPC - Sets the preconditioner to be used. 341931823bd8SMatthew G Knepley 342031823bd8SMatthew G Knepley Collective on SNES 342131823bd8SMatthew G Knepley 342231823bd8SMatthew G Knepley Input Parameters: 342331823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 342431823bd8SMatthew G Knepley - pc - the preconditioner object 342531823bd8SMatthew G Knepley 342631823bd8SMatthew G Knepley Notes: 342731823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 342831823bd8SMatthew G Knepley to configure it using the API). 342931823bd8SMatthew G Knepley 343031823bd8SMatthew G Knepley Level: developer 343131823bd8SMatthew G Knepley 343231823bd8SMatthew G Knepley .keywords: SNES, set, precondition 343331823bd8SMatthew G Knepley .seealso: SNESGetPC() 343431823bd8SMatthew G Knepley @*/ 343531823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 343631823bd8SMatthew G Knepley { 343731823bd8SMatthew G Knepley PetscErrorCode ierr; 343831823bd8SMatthew G Knepley 343931823bd8SMatthew G Knepley PetscFunctionBegin; 344031823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 344131823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 344231823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 344331823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 3444bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 344531823bd8SMatthew G Knepley snes->pc = pc; 344631823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 344731823bd8SMatthew G Knepley PetscFunctionReturn(0); 344831823bd8SMatthew G Knepley } 344931823bd8SMatthew G Knepley 345031823bd8SMatthew G Knepley #undef __FUNCT__ 345131823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 345231823bd8SMatthew G Knepley /*@ 345331823bd8SMatthew G Knepley SNESGetPC - Returns a pointer to the preconditioner context set with SNESSetPC(). 345431823bd8SMatthew G Knepley 345531823bd8SMatthew G Knepley Not Collective 345631823bd8SMatthew G Knepley 345731823bd8SMatthew G Knepley Input Parameter: 345831823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 345931823bd8SMatthew G Knepley 346031823bd8SMatthew G Knepley Output Parameter: 346131823bd8SMatthew G Knepley . pc - preconditioner context 346231823bd8SMatthew G Knepley 346331823bd8SMatthew G Knepley Level: developer 346431823bd8SMatthew G Knepley 346531823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 346631823bd8SMatthew G Knepley .seealso: SNESSetPC() 346731823bd8SMatthew G Knepley @*/ 346831823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 346931823bd8SMatthew G Knepley { 347031823bd8SMatthew G Knepley PetscErrorCode ierr; 347131823bd8SMatthew G Knepley 347231823bd8SMatthew G Knepley PetscFunctionBegin; 347331823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 347431823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 347531823bd8SMatthew G Knepley if (!snes->pc) { 347631823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr); 347731823bd8SMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 0);CHKERRQ(ierr); 347831823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 347931823bd8SMatthew G Knepley } 348031823bd8SMatthew G Knepley *pc = snes->pc; 348131823bd8SMatthew G Knepley PetscFunctionReturn(0); 348231823bd8SMatthew G Knepley } 348331823bd8SMatthew G Knepley 348469b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3485c6db04a5SJed Brown #include <mex.h> 348669b4f73cSBarry Smith 34878f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 34888f6e6473SBarry Smith 34890807856dSBarry Smith #undef __FUNCT__ 34900807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 34910807856dSBarry Smith /* 34920807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 34930807856dSBarry Smith SNESSetFunctionMatlab(). 34940807856dSBarry Smith 34950807856dSBarry Smith Collective on SNES 34960807856dSBarry Smith 34970807856dSBarry Smith Input Parameters: 34980807856dSBarry Smith + snes - the SNES context 34990807856dSBarry Smith - x - input vector 35000807856dSBarry Smith 35010807856dSBarry Smith Output Parameter: 35020807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 35030807856dSBarry Smith 35040807856dSBarry Smith Notes: 35050807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 35060807856dSBarry Smith implementations, so most users would not generally call this routine 35070807856dSBarry Smith themselves. 35080807856dSBarry Smith 35090807856dSBarry Smith Level: developer 35100807856dSBarry Smith 35110807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 35120807856dSBarry Smith 35130807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 351461b2408cSBarry Smith */ 35157087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 35160807856dSBarry Smith { 3517e650e774SBarry Smith PetscErrorCode ierr; 35188f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 35198f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 35208f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 352191621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 3522e650e774SBarry Smith 35230807856dSBarry Smith PetscFunctionBegin; 35240807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35250807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 35260807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 35270807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 35280807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 35290807856dSBarry Smith 35300807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 3531e650e774SBarry Smith 353291621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3533e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3534e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 353591621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 353691621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 353791621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 35388f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 35398f6e6473SBarry Smith prhs[4] = sctx->ctx; 3540b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 3541e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3542e650e774SBarry Smith mxDestroyArray(prhs[0]); 3543e650e774SBarry Smith mxDestroyArray(prhs[1]); 3544e650e774SBarry Smith mxDestroyArray(prhs[2]); 35458f6e6473SBarry Smith mxDestroyArray(prhs[3]); 3546e650e774SBarry Smith mxDestroyArray(plhs[0]); 35470807856dSBarry Smith PetscFunctionReturn(0); 35480807856dSBarry Smith } 35490807856dSBarry Smith 35500807856dSBarry Smith 35510807856dSBarry Smith #undef __FUNCT__ 35520807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 355361b2408cSBarry Smith /* 35540807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 35550807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 3556e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 35570807856dSBarry Smith 35580807856dSBarry Smith Logically Collective on SNES 35590807856dSBarry Smith 35600807856dSBarry Smith Input Parameters: 35610807856dSBarry Smith + snes - the SNES context 35620807856dSBarry Smith . r - vector to store function value 35630807856dSBarry Smith - func - function evaluation routine 35640807856dSBarry Smith 35650807856dSBarry Smith Calling sequence of func: 356661b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 35670807856dSBarry Smith 35680807856dSBarry Smith 35690807856dSBarry Smith Notes: 35700807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 35710807856dSBarry Smith $ f'(x) x = -f(x), 35720807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 35730807856dSBarry Smith 35740807856dSBarry Smith Level: beginner 35750807856dSBarry Smith 35760807856dSBarry Smith .keywords: SNES, nonlinear, set, function 35770807856dSBarry Smith 35780807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 357961b2408cSBarry Smith */ 35807087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 35810807856dSBarry Smith { 35820807856dSBarry Smith PetscErrorCode ierr; 35838f6e6473SBarry Smith SNESMatlabContext *sctx; 35840807856dSBarry Smith 35850807856dSBarry Smith PetscFunctionBegin; 35868f6e6473SBarry Smith /* currently sctx is memory bleed */ 35878f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 35888f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 35898f6e6473SBarry Smith /* 35908f6e6473SBarry Smith This should work, but it doesn't 35918f6e6473SBarry Smith sctx->ctx = ctx; 35928f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 35938f6e6473SBarry Smith */ 35948f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 35958f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 35960807856dSBarry Smith PetscFunctionReturn(0); 35970807856dSBarry Smith } 359869b4f73cSBarry Smith 359961b2408cSBarry Smith #undef __FUNCT__ 360061b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 360161b2408cSBarry Smith /* 360261b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 360361b2408cSBarry Smith SNESSetJacobianMatlab(). 360461b2408cSBarry Smith 360561b2408cSBarry Smith Collective on SNES 360661b2408cSBarry Smith 360761b2408cSBarry Smith Input Parameters: 360861b2408cSBarry Smith + snes - the SNES context 360961b2408cSBarry Smith . x - input vector 361061b2408cSBarry Smith . A, B - the matrices 361161b2408cSBarry Smith - ctx - user context 361261b2408cSBarry Smith 361361b2408cSBarry Smith Output Parameter: 361461b2408cSBarry Smith . flag - structure of the matrix 361561b2408cSBarry Smith 361661b2408cSBarry Smith Level: developer 361761b2408cSBarry Smith 361861b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 361961b2408cSBarry Smith 362061b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 362161b2408cSBarry Smith @*/ 36227087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 362361b2408cSBarry Smith { 362461b2408cSBarry Smith PetscErrorCode ierr; 362561b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 362661b2408cSBarry Smith int nlhs = 2,nrhs = 6; 362761b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 362861b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 362961b2408cSBarry Smith 363061b2408cSBarry Smith PetscFunctionBegin; 363161b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 363261b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 363361b2408cSBarry Smith 363461b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 363561b2408cSBarry Smith 363661b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 363761b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 363861b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 363961b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 364061b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 364161b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 364261b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 364361b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 364461b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 364561b2408cSBarry Smith prhs[5] = sctx->ctx; 3646b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 364761b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 364861b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 364961b2408cSBarry Smith mxDestroyArray(prhs[0]); 365061b2408cSBarry Smith mxDestroyArray(prhs[1]); 365161b2408cSBarry Smith mxDestroyArray(prhs[2]); 365261b2408cSBarry Smith mxDestroyArray(prhs[3]); 365361b2408cSBarry Smith mxDestroyArray(prhs[4]); 365461b2408cSBarry Smith mxDestroyArray(plhs[0]); 365561b2408cSBarry Smith mxDestroyArray(plhs[1]); 365661b2408cSBarry Smith PetscFunctionReturn(0); 365761b2408cSBarry Smith } 365861b2408cSBarry Smith 365961b2408cSBarry Smith 366061b2408cSBarry Smith #undef __FUNCT__ 366161b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 366261b2408cSBarry Smith /* 366361b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 366461b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 3665e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 366661b2408cSBarry Smith 366761b2408cSBarry Smith Logically Collective on SNES 366861b2408cSBarry Smith 366961b2408cSBarry Smith Input Parameters: 367061b2408cSBarry Smith + snes - the SNES context 367161b2408cSBarry Smith . A,B - Jacobian matrices 367261b2408cSBarry Smith . func - function evaluation routine 367361b2408cSBarry Smith - ctx - user context 367461b2408cSBarry Smith 367561b2408cSBarry Smith Calling sequence of func: 367661b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 367761b2408cSBarry Smith 367861b2408cSBarry Smith 367961b2408cSBarry Smith Level: developer 368061b2408cSBarry Smith 368161b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 368261b2408cSBarry Smith 368361b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 368461b2408cSBarry Smith */ 36857087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 368661b2408cSBarry Smith { 368761b2408cSBarry Smith PetscErrorCode ierr; 368861b2408cSBarry Smith SNESMatlabContext *sctx; 368961b2408cSBarry Smith 369061b2408cSBarry Smith PetscFunctionBegin; 369161b2408cSBarry Smith /* currently sctx is memory bleed */ 369261b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 369361b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 369461b2408cSBarry Smith /* 369561b2408cSBarry Smith This should work, but it doesn't 369661b2408cSBarry Smith sctx->ctx = ctx; 369761b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 369861b2408cSBarry Smith */ 369961b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 370061b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 370161b2408cSBarry Smith PetscFunctionReturn(0); 370261b2408cSBarry Smith } 370369b4f73cSBarry Smith 3704f9eb7ae2SShri Abhyankar #undef __FUNCT__ 3705f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 3706f9eb7ae2SShri Abhyankar /* 3707f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 3708f9eb7ae2SShri Abhyankar 3709f9eb7ae2SShri Abhyankar Collective on SNES 3710f9eb7ae2SShri Abhyankar 3711f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 3712f9eb7ae2SShri Abhyankar @*/ 37137087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 3714f9eb7ae2SShri Abhyankar { 3715f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 371648f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3717f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 3718f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 3719f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 3720f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 3721f9eb7ae2SShri Abhyankar 3722f9eb7ae2SShri Abhyankar PetscFunctionBegin; 3723f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3724f9eb7ae2SShri Abhyankar 3725f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3726f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3727f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 3728f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 3729f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 3730f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 3731f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 3732f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 3733f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 3734f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3735f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 3736f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 3737f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 3738f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 3739f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 3740f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 3741f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 3742f9eb7ae2SShri Abhyankar } 3743f9eb7ae2SShri Abhyankar 3744f9eb7ae2SShri Abhyankar 3745f9eb7ae2SShri Abhyankar #undef __FUNCT__ 3746f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 3747f9eb7ae2SShri Abhyankar /* 3748e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 3749f9eb7ae2SShri Abhyankar 3750f9eb7ae2SShri Abhyankar Level: developer 3751f9eb7ae2SShri Abhyankar 3752f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 3753f9eb7ae2SShri Abhyankar 3754f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3755f9eb7ae2SShri Abhyankar */ 37567087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 3757f9eb7ae2SShri Abhyankar { 3758f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 3759f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 3760f9eb7ae2SShri Abhyankar 3761f9eb7ae2SShri Abhyankar PetscFunctionBegin; 3762f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 3763f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3764f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3765f9eb7ae2SShri Abhyankar /* 3766f9eb7ae2SShri Abhyankar This should work, but it doesn't 3767f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 3768f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 3769f9eb7ae2SShri Abhyankar */ 3770f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 3771f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 3772f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 3773f9eb7ae2SShri Abhyankar } 3774f9eb7ae2SShri Abhyankar 377569b4f73cSBarry Smith #endif 3776