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; 9701cf23dSPeter Brune PetscLogEvent SNES_Solve, SNES_LineSearch, SNES_FunctionEval, SNES_JacobianEval, SNES_GSEval; 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; 57dd568438SSatish Balay 58e113a28aSBarry Smith PetscFunctionReturn(0); 59e113a28aSBarry Smith } 60e113a28aSBarry Smith 61e113a28aSBarry Smith #undef __FUNCT__ 62e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged" 63e113a28aSBarry Smith /*@ 64e113a28aSBarry Smith SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge? 65e113a28aSBarry Smith 66e113a28aSBarry Smith Not Collective 67e113a28aSBarry Smith 68e113a28aSBarry Smith Input Parameter: 69e113a28aSBarry Smith . snes - iterative context obtained from SNESCreate() 70e113a28aSBarry Smith 71e113a28aSBarry Smith Output Parameter: 72e113a28aSBarry Smith . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE 73e113a28aSBarry Smith 74e113a28aSBarry Smith Level: intermediate 75e113a28aSBarry Smith 76e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 77e113a28aSBarry Smith 78e113a28aSBarry Smith .seealso: SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 79e113a28aSBarry Smith @*/ 807087cfbeSBarry Smith PetscErrorCode SNESGetErrorIfNotConverged(SNES snes,PetscBool *flag) 81e113a28aSBarry Smith { 82e113a28aSBarry Smith PetscFunctionBegin; 83e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 84e113a28aSBarry Smith PetscValidPointer(flag,2); 85e113a28aSBarry Smith *flag = snes->errorifnotconverged; 86e113a28aSBarry Smith PetscFunctionReturn(0); 87e113a28aSBarry Smith } 88e113a28aSBarry Smith 89e113a28aSBarry Smith #undef __FUNCT__ 904936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError" 91e725d27bSBarry Smith /*@ 924936397dSBarry Smith SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not 934936397dSBarry Smith in the functions domain. For example, negative pressure. 944936397dSBarry Smith 953f9fe445SBarry Smith Logically Collective on SNES 964936397dSBarry Smith 974936397dSBarry Smith Input Parameters: 984936397dSBarry Smith . SNES - the SNES context 994936397dSBarry Smith 10028529972SSatish Balay Level: advanced 1014936397dSBarry Smith 1024936397dSBarry Smith .keywords: SNES, view 1034936397dSBarry Smith 1044936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction() 1054936397dSBarry Smith @*/ 1067087cfbeSBarry Smith PetscErrorCode SNESSetFunctionDomainError(SNES snes) 1074936397dSBarry Smith { 1084936397dSBarry Smith PetscFunctionBegin; 1090700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1104936397dSBarry Smith snes->domainerror = PETSC_TRUE; 1114936397dSBarry Smith PetscFunctionReturn(0); 1124936397dSBarry Smith } 1134936397dSBarry Smith 1144936397dSBarry Smith #undef __FUNCT__ 1154a2ae208SSatish Balay #define __FUNCT__ "SNESView" 1167e2c5f70SBarry Smith /*@C 1179b94acceSBarry Smith SNESView - Prints the SNES data structure. 1189b94acceSBarry Smith 1194c49b128SBarry Smith Collective on SNES 120fee21e36SBarry Smith 121c7afd0dbSLois Curfman McInnes Input Parameters: 122c7afd0dbSLois Curfman McInnes + SNES - the SNES context 123c7afd0dbSLois Curfman McInnes - viewer - visualization context 124c7afd0dbSLois Curfman McInnes 1259b94acceSBarry Smith Options Database Key: 126c8a8ba5cSLois Curfman McInnes . -snes_view - Calls SNESView() at end of SNESSolve() 1279b94acceSBarry Smith 1289b94acceSBarry Smith Notes: 1299b94acceSBarry Smith The available visualization contexts include 130b0a32e0cSBarry Smith + PETSC_VIEWER_STDOUT_SELF - standard output (default) 131b0a32e0cSBarry Smith - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 132c8a8ba5cSLois Curfman McInnes output where only the first processor opens 133c8a8ba5cSLois Curfman McInnes the file. All other processors send their 134c8a8ba5cSLois Curfman McInnes data to the first processor to print. 1359b94acceSBarry Smith 1363e081fefSLois Curfman McInnes The user can open an alternative visualization context with 137b0a32e0cSBarry Smith PetscViewerASCIIOpen() - output to a specified file. 1389b94acceSBarry Smith 13936851e7fSLois Curfman McInnes Level: beginner 14036851e7fSLois Curfman McInnes 1419b94acceSBarry Smith .keywords: SNES, view 1429b94acceSBarry Smith 143b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen() 1449b94acceSBarry Smith @*/ 1457087cfbeSBarry Smith PetscErrorCode SNESView(SNES snes,PetscViewer viewer) 1469b94acceSBarry Smith { 147fa9f3622SBarry Smith SNESKSPEW *kctx; 148dfbe8321SBarry Smith PetscErrorCode ierr; 14994b7f48cSBarry Smith KSP ksp; 150ace3abfcSBarry Smith PetscBool iascii,isstring; 1519b94acceSBarry Smith 1523a40ed3dSBarry Smith PetscFunctionBegin; 1530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1543050cee2SBarry Smith if (!viewer) { 1557adad957SLisandro Dalcin ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 1563050cee2SBarry Smith } 1570700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 158c9780b6fSBarry Smith PetscCheckSameComm(snes,1,viewer,2); 15974679c65SBarry Smith 1602692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1612692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 16232077d6dSBarry Smith if (iascii) { 163317d6ea6SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr); 164e7788613SBarry Smith if (snes->ops->view) { 165b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 166e7788613SBarry Smith ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 167b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1680ef38995SBarry Smith } 16977431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr); 170a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%G, absolute=%G, solution=%G\n", 17170441072SBarry Smith snes->rtol,snes->abstol,snes->xtol);CHKERRQ(ierr); 17277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr); 17377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr); 1749b94acceSBarry Smith if (snes->ksp_ewconv) { 175fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 1769b94acceSBarry Smith if (kctx) { 17777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr); 178a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr); 179a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr); 1809b94acceSBarry Smith } 1819b94acceSBarry Smith } 182eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 183eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n");CHKERRQ(ierr); 184eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 185eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr); 186eb1f6c34SBarry Smith } 187eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 188eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n");CHKERRQ(ierr); 189eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 19042f4f86dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr); 191eb1f6c34SBarry Smith } 1920f5bd95cSBarry Smith } else if (isstring) { 193317d6ea6SBarry Smith const char *type; 194454a90a3SBarry Smith ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 195b0a32e0cSBarry Smith ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr); 19619bcc07fSBarry Smith } 19742f4f86dSBarry Smith if (snes->pc && snes->usespc) { 1984a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1994a0c5b0cSMatthew G Knepley ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr); 2004a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2014a0c5b0cSMatthew G Knepley } 2022c155ee1SBarry Smith if (snes->usesksp) { 2032c155ee1SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 204b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 20594b7f48cSBarry Smith ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 206b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2072c155ee1SBarry Smith } 2083a40ed3dSBarry Smith PetscFunctionReturn(0); 2099b94acceSBarry Smith } 2109b94acceSBarry Smith 21176b2cf59SMatthew Knepley /* 21276b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 21376b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 21476b2cf59SMatthew Knepley */ 21576b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 216a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 2176849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 21876b2cf59SMatthew Knepley 219e74ef692SMatthew Knepley #undef __FUNCT__ 220e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker" 221ac226902SBarry Smith /*@C 22276b2cf59SMatthew Knepley SNESAddOptionsChecker - Adds an additional function to check for SNES options. 22376b2cf59SMatthew Knepley 22476b2cf59SMatthew Knepley Not Collective 22576b2cf59SMatthew Knepley 22676b2cf59SMatthew Knepley Input Parameter: 22776b2cf59SMatthew Knepley . snescheck - function that checks for options 22876b2cf59SMatthew Knepley 22976b2cf59SMatthew Knepley Level: developer 23076b2cf59SMatthew Knepley 23176b2cf59SMatthew Knepley .seealso: SNESSetFromOptions() 23276b2cf59SMatthew Knepley @*/ 2337087cfbeSBarry Smith PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 23476b2cf59SMatthew Knepley { 23576b2cf59SMatthew Knepley PetscFunctionBegin; 23676b2cf59SMatthew Knepley if (numberofsetfromoptions >= MAXSETFROMOPTIONS) { 237e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 23876b2cf59SMatthew Knepley } 23976b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 24076b2cf59SMatthew Knepley PetscFunctionReturn(0); 24176b2cf59SMatthew Knepley } 24276b2cf59SMatthew Knepley 2437087cfbeSBarry Smith extern PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 244aa3661deSLisandro Dalcin 245aa3661deSLisandro Dalcin #undef __FUNCT__ 246aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private" 247ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 248aa3661deSLisandro Dalcin { 249aa3661deSLisandro Dalcin Mat J; 250aa3661deSLisandro Dalcin KSP ksp; 251aa3661deSLisandro Dalcin PC pc; 252ace3abfcSBarry Smith PetscBool match; 253aa3661deSLisandro Dalcin PetscErrorCode ierr; 254aa3661deSLisandro Dalcin 255aa3661deSLisandro Dalcin PetscFunctionBegin; 2560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 257aa3661deSLisandro Dalcin 25898613b67SLisandro Dalcin if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 25998613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 26098613b67SLisandro Dalcin ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr); 26198613b67SLisandro Dalcin } 26298613b67SLisandro Dalcin 263aa3661deSLisandro Dalcin if (version == 1) { 264aa3661deSLisandro Dalcin ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 26598613b67SLisandro Dalcin ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 2669c6ac3b3SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 267aa3661deSLisandro Dalcin } else if (version == 2) { 268e32f2f54SBarry Smith if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 26982a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 270aa3661deSLisandro Dalcin ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr); 271aa3661deSLisandro Dalcin #else 272e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)"); 273aa3661deSLisandro Dalcin #endif 274a8248277SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2"); 275aa3661deSLisandro Dalcin 276aa3661deSLisandro Dalcin ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr); 277d3462f78SMatthew Knepley if (hasOperator) { 278aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 279aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 280aa3661deSLisandro Dalcin ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 281aa3661deSLisandro Dalcin } else { 282aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 283aa3661deSLisandro Dalcin provided preconditioner matrix with the default matrix free version. */ 284aa3661deSLisandro Dalcin ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);CHKERRQ(ierr); 285aa3661deSLisandro Dalcin /* Force no preconditioner */ 286aa3661deSLisandro Dalcin ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 287aa3661deSLisandro Dalcin ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 288aa3661deSLisandro Dalcin ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr); 289aa3661deSLisandro Dalcin if (!match) { 290aa3661deSLisandro Dalcin ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 291aa3661deSLisandro Dalcin ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 292aa3661deSLisandro Dalcin } 293aa3661deSLisandro Dalcin } 2946bf464f9SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 295aa3661deSLisandro Dalcin PetscFunctionReturn(0); 296aa3661deSLisandro Dalcin } 297aa3661deSLisandro Dalcin 2984a2ae208SSatish Balay #undef __FUNCT__ 2994a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions" 3009b94acceSBarry Smith /*@ 30194b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 3029b94acceSBarry Smith 303c7afd0dbSLois Curfman McInnes Collective on SNES 304c7afd0dbSLois Curfman McInnes 3059b94acceSBarry Smith Input Parameter: 3069b94acceSBarry Smith . snes - the SNES context 3079b94acceSBarry Smith 30836851e7fSLois Curfman McInnes Options Database Keys: 309ea630c6eSPeter Brune + -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas 31082738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 31182738288SBarry Smith of the change in the solution between steps 31270441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 313b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 314b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 315b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 316*4839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 317ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 318a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 319e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 320b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 3212492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 32282738288SBarry Smith solver; hence iterations will continue until max_it 3231fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 32482738288SBarry Smith of convergence test 325e8105e01SRichard Katz . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 326e8105e01SRichard Katz filename given prints to stdout 327a6570f20SBarry Smith . -snes_monitor_solution - plots solution at each iteration 328a6570f20SBarry Smith . -snes_monitor_residual - plots residual (not its norm) at each iteration 329a6570f20SBarry Smith . -snes_monitor_solution_update - plots update to solution at each iteration 330a6570f20SBarry Smith . -snes_monitor_draw - plots residual norm at each iteration 331e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 3325968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 333fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 33482738288SBarry Smith 33582738288SBarry Smith Options Database for Eisenstat-Walker method: 336fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 3374b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 33836851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 33936851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 34036851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 34136851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 34236851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 34336851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 34482738288SBarry Smith 34511ca99fdSLois Curfman McInnes Notes: 34611ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 3470598bfebSBarry Smith the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>. 34883e2fdc7SBarry Smith 34936851e7fSLois Curfman McInnes Level: beginner 35036851e7fSLois Curfman McInnes 3519b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 3529b94acceSBarry Smith 35369ed319cSSatish Balay .seealso: SNESSetOptionsPrefix() 3549b94acceSBarry Smith @*/ 3557087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 3569b94acceSBarry Smith { 357ea630c6eSPeter Brune PetscBool flg,set,mf,mf_operator,pcset; 358efd51863SBarry Smith PetscInt i,indx,lag,mf_version,grids; 359aa3661deSLisandro Dalcin MatStructure matflag; 36085385478SLisandro Dalcin const char *deft = SNESLS; 36185385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 36285385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 363e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 36451e86f29SPeter Brune const char *optionsprefix; 365649052a6SBarry Smith PetscViewer monviewer; 36685385478SLisandro Dalcin PetscErrorCode ierr; 3679b94acceSBarry Smith 3683a40ed3dSBarry Smith PetscFunctionBegin; 3690700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 370ca161407SBarry Smith 371186905e3SBarry Smith if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 3723194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 3737adad957SLisandro Dalcin if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; } 374b0a32e0cSBarry Smith ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 375d64ed03dSBarry Smith if (flg) { 376186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 3777adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 378186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 379d64ed03dSBarry Smith } 38090d69ab7SBarry Smith /* not used here, but called so will go into help messaage */ 381909c8a9fSBarry Smith ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 38293c39befSBarry Smith 38357034d6fSHong Zhang ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->xtol,&snes->xtol,0);CHKERRQ(ierr); 38457034d6fSHong Zhang ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 385186905e3SBarry Smith 38657034d6fSHong Zhang ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 387b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 388b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 38950ffb88aSMatthew Knepley ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 390ddf469c8SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr); 391acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr); 39285385478SLisandro Dalcin 393a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 394a8054027SBarry Smith if (flg) { 395a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 396a8054027SBarry Smith } 397e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 398e35cf81dSBarry Smith if (flg) { 399e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 400e35cf81dSBarry Smith } 401efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 402efd51863SBarry Smith if (flg) { 403efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 404efd51863SBarry Smith } 405a8054027SBarry Smith 40685385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 40785385478SLisandro Dalcin if (flg) { 40885385478SLisandro Dalcin switch (indx) { 4097f7931b9SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 4107f7931b9SBarry Smith case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 41185385478SLisandro Dalcin } 41285385478SLisandro Dalcin } 41385385478SLisandro Dalcin 414acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr); 415186905e3SBarry Smith 41685385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 41785385478SLisandro Dalcin 418acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 419186905e3SBarry Smith 420fa9f3622SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 421fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 422fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 423fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 424fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 425fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 426fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 427186905e3SBarry Smith 42890d69ab7SBarry Smith flg = PETSC_FALSE; 429acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 430a6570f20SBarry Smith if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 431eabae89aSBarry Smith 432a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 433e8105e01SRichard Katz if (flg) { 434649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 435649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 436e8105e01SRichard Katz } 437eabae89aSBarry Smith 438b271bb04SBarry Smith ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 439b271bb04SBarry Smith if (flg) { 440b271bb04SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 441b271bb04SBarry Smith } 442b271bb04SBarry Smith 443a6570f20SBarry Smith ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 444eabae89aSBarry Smith if (flg) { 445649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 446f1bef1bcSMatthew Knepley ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 447e8105e01SRichard Katz } 448eabae89aSBarry Smith 449a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 450eabae89aSBarry Smith if (flg) { 451649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 452649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 453eabae89aSBarry Smith } 454eabae89aSBarry Smith 4555180491cSLisandro Dalcin ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 4565180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 4575180491cSLisandro Dalcin 45890d69ab7SBarry Smith flg = PETSC_FALSE; 459acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 460a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 46190d69ab7SBarry Smith flg = PETSC_FALSE; 462acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 463a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 46490d69ab7SBarry Smith flg = PETSC_FALSE; 465acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 466a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 46790d69ab7SBarry Smith flg = PETSC_FALSE; 468acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 469a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 47090d69ab7SBarry Smith flg = PETSC_FALSE; 471acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 472b271bb04SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 473e24b481bSBarry Smith 47490d69ab7SBarry Smith flg = PETSC_FALSE; 475acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 4764b27c08aSLois Curfman McInnes if (flg) { 477186905e3SBarry Smith ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);CHKERRQ(ierr); 478ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 4799b94acceSBarry Smith } 480639f9d9dSBarry Smith 481aa3661deSLisandro Dalcin mf = mf_operator = PETSC_FALSE; 482aa3661deSLisandro Dalcin flg = PETSC_FALSE; 483acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr); 484a8248277SBarry Smith if (flg && mf_operator) { 485a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 486a8248277SBarry Smith mf = PETSC_TRUE; 487a8248277SBarry Smith } 488aa3661deSLisandro Dalcin flg = PETSC_FALSE; 489acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr); 490aa3661deSLisandro Dalcin if (!flg && mf_operator) mf = PETSC_TRUE; 491aa3661deSLisandro Dalcin mf_version = 1; 492aa3661deSLisandro Dalcin ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr); 493aa3661deSLisandro Dalcin 494d28543b3SPeter Brune 49589b92e6fSPeter Brune /* GS Options */ 496d28543b3SPeter Brune ierr = PetscOptionsBool("-snes_use_gs","Use user-provided GS routine","SNESSetUseGS",snes->usegs,&snes->usegs,PETSC_NULL);CHKERRQ(ierr); 49789b92e6fSPeter Brune ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr); 49889b92e6fSPeter Brune 499d28543b3SPeter Brune 500ea630c6eSPeter Brune /* line search options */ 501ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_alpha","Constant function norm must decrease by","None",snes->ls_alpha,&snes->ls_alpha,0);CHKERRQ(ierr); 502ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_maxstep","Step must be less than","None",snes->maxstep,&snes->maxstep,0);CHKERRQ(ierr); 503ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_steptol","Minimum lambda allowed","None",snes->steptol,&snes->steptol,0);CHKERRQ(ierr); 504ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_damping","Damping parameter","SNES",snes->damping,&snes->damping,&flg);CHKERRQ(ierr); 505af60355fSPeter Brune ierr = PetscOptionsInt("-snes_ls_it" ,"Line search iterations","SNES",snes->ls_its,&snes->ls_its,&flg);CHKERRQ(ierr); 506ea630c6eSPeter Brune ierr = PetscOptionsBool("-snes_ls_monitor","Print progress of line searches","SNESLineSearchSetMonitor",snes->ls_monitor ? PETSC_TRUE : PETSC_FALSE,&flg,&set);CHKERRQ(ierr); 507ea630c6eSPeter Brune if (set) {ierr = SNESLineSearchSetMonitor(snes,flg);CHKERRQ(ierr);} 50815f5eeeaSPeter Brune ierr = PetscOptionsEnum("-snes_ls","Line search used","SNESLineSearchSet",SNESLineSearchTypes,(PetscEnum)snes->ls_type,(PetscEnum*)&indx,&flg);CHKERRQ(ierr); 50915f5eeeaSPeter Brune if (flg) { 510ea630c6eSPeter Brune ierr = SNESLineSearchSetType(snes,(SNESLineSearchType)indx);CHKERRQ(ierr); 51115f5eeeaSPeter Brune } 5128e3fc8c0SJed Brown flg = snes->ops->precheckstep == SNESLineSearchPreCheckPicard ? PETSC_TRUE : PETSC_FALSE; 5138e3fc8c0SJed Brown ierr = PetscOptionsBool("-snes_ls_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);CHKERRQ(ierr); 5148e3fc8c0SJed Brown if (set) { 5158e3fc8c0SJed Brown if (flg) { 5168e3fc8c0SJed Brown snes->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */ 5178e3fc8c0SJed Brown ierr = PetscOptionsReal("-snes_ls_precheck_picard_angle","Maximum angle at which to activate the correction","none",snes->precheck_picard_angle,&snes->precheck_picard_angle,PETSC_NULL);CHKERRQ(ierr); 5188e3fc8c0SJed Brown ierr = SNESLineSearchSetPreCheck(snes,SNESLineSearchPreCheckPicard,&snes->precheck_picard_angle);CHKERRQ(ierr); 5198e3fc8c0SJed Brown } else { 5208e3fc8c0SJed Brown ierr = SNESLineSearchSetPreCheck(snes,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 5218e3fc8c0SJed Brown } 5228e3fc8c0SJed Brown } 5238e3fc8c0SJed Brown 52476b2cf59SMatthew Knepley for(i = 0; i < numberofsetfromoptions; i++) { 52576b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 52676b2cf59SMatthew Knepley } 52776b2cf59SMatthew Knepley 528e7788613SBarry Smith if (snes->ops->setfromoptions) { 529e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 530639f9d9dSBarry Smith } 5315d973c19SBarry Smith 5325d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 5335d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 534b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 5354bbc92c1SBarry Smith 536aa3661deSLisandro Dalcin if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 5371cee3971SBarry Smith 5381cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 539aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 540aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 54185385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 54293993e2dSLois Curfman McInnes 54351e86f29SPeter Brune /* if someone has set the SNES PC type, create it. */ 54451e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 54551e86f29SPeter Brune ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 54651e86f29SPeter Brune if (pcset && (!snes->pc)) { 54751e86f29SPeter Brune ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr); 54851e86f29SPeter Brune } 5494a0c5b0cSMatthew G Knepley if (snes->pc) { 5504a0c5b0cSMatthew G Knepley ierr = SNESSetOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr); 5514a0c5b0cSMatthew G Knepley ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 552646217ecSPeter Brune ierr = SNESSetGS(snes->pc, snes->ops->computegs, snes->gsP);CHKERRQ(ierr); 5534a0c5b0cSMatthew G Knepley /* Should we make a duplicate vector and matrix? Leave the DM to make it? */ 5544a0c5b0cSMatthew G Knepley ierr = SNESSetFunction(snes->pc, snes->vec_func, snes->ops->computefunction, snes->funP);CHKERRQ(ierr); 5554a0c5b0cSMatthew G Knepley ierr = SNESSetJacobian(snes->pc, snes->jacobian, snes->jacobian_pre, snes->ops->computejacobian, snes->jacP);CHKERRQ(ierr); 5564a0c5b0cSMatthew G Knepley ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 5574a0c5b0cSMatthew G Knepley } 5583a40ed3dSBarry Smith PetscFunctionReturn(0); 5599b94acceSBarry Smith } 5609b94acceSBarry Smith 561d25893d9SBarry Smith #undef __FUNCT__ 562d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 563d25893d9SBarry Smith /*@ 564d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 565d25893d9SBarry Smith the nonlinear solvers. 566d25893d9SBarry Smith 567d25893d9SBarry Smith Logically Collective on SNES 568d25893d9SBarry Smith 569d25893d9SBarry Smith Input Parameters: 570d25893d9SBarry Smith + snes - the SNES context 571d25893d9SBarry Smith . compute - function to compute the context 572d25893d9SBarry Smith - destroy - function to destroy the context 573d25893d9SBarry Smith 574d25893d9SBarry Smith Level: intermediate 575d25893d9SBarry Smith 576d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 577d25893d9SBarry Smith 578d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 579d25893d9SBarry Smith @*/ 580d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 581d25893d9SBarry Smith { 582d25893d9SBarry Smith PetscFunctionBegin; 583d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 584d25893d9SBarry Smith snes->ops->usercompute = compute; 585d25893d9SBarry Smith snes->ops->userdestroy = destroy; 586d25893d9SBarry Smith PetscFunctionReturn(0); 587d25893d9SBarry Smith } 588a847f771SSatish Balay 5894a2ae208SSatish Balay #undef __FUNCT__ 5904a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 591b07ff414SBarry Smith /*@ 5929b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 5939b94acceSBarry Smith the nonlinear solvers. 5949b94acceSBarry Smith 5953f9fe445SBarry Smith Logically Collective on SNES 596fee21e36SBarry Smith 597c7afd0dbSLois Curfman McInnes Input Parameters: 598c7afd0dbSLois Curfman McInnes + snes - the SNES context 599c7afd0dbSLois Curfman McInnes - usrP - optional user context 600c7afd0dbSLois Curfman McInnes 60136851e7fSLois Curfman McInnes Level: intermediate 60236851e7fSLois Curfman McInnes 6039b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 6049b94acceSBarry Smith 605d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext() 6069b94acceSBarry Smith @*/ 6077087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 6089b94acceSBarry Smith { 6091b2093e4SBarry Smith PetscErrorCode ierr; 610b07ff414SBarry Smith KSP ksp; 6111b2093e4SBarry Smith 6123a40ed3dSBarry Smith PetscFunctionBegin; 6130700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 614b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 615b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 6169b94acceSBarry Smith snes->user = usrP; 6173a40ed3dSBarry Smith PetscFunctionReturn(0); 6189b94acceSBarry Smith } 61974679c65SBarry Smith 6204a2ae208SSatish Balay #undef __FUNCT__ 6214a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 622b07ff414SBarry Smith /*@ 6239b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 6249b94acceSBarry Smith nonlinear solvers. 6259b94acceSBarry Smith 626c7afd0dbSLois Curfman McInnes Not Collective 627c7afd0dbSLois Curfman McInnes 6289b94acceSBarry Smith Input Parameter: 6299b94acceSBarry Smith . snes - SNES context 6309b94acceSBarry Smith 6319b94acceSBarry Smith Output Parameter: 6329b94acceSBarry Smith . usrP - user context 6339b94acceSBarry Smith 63436851e7fSLois Curfman McInnes Level: intermediate 63536851e7fSLois Curfman McInnes 6369b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 6379b94acceSBarry Smith 6389b94acceSBarry Smith .seealso: SNESSetApplicationContext() 6399b94acceSBarry Smith @*/ 640e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 6419b94acceSBarry Smith { 6423a40ed3dSBarry Smith PetscFunctionBegin; 6430700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 644e71120c6SJed Brown *(void**)usrP = snes->user; 6453a40ed3dSBarry Smith PetscFunctionReturn(0); 6469b94acceSBarry Smith } 64774679c65SBarry Smith 6484a2ae208SSatish Balay #undef __FUNCT__ 6494a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 6509b94acceSBarry Smith /*@ 651c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 652c8228a4eSBarry Smith at this time. 6539b94acceSBarry Smith 654c7afd0dbSLois Curfman McInnes Not Collective 655c7afd0dbSLois Curfman McInnes 6569b94acceSBarry Smith Input Parameter: 6579b94acceSBarry Smith . snes - SNES context 6589b94acceSBarry Smith 6599b94acceSBarry Smith Output Parameter: 6609b94acceSBarry Smith . iter - iteration number 6619b94acceSBarry Smith 662c8228a4eSBarry Smith Notes: 663c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 664c8228a4eSBarry Smith 665c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 66608405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 66708405cd6SLois Curfman McInnes .vb 66808405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 66908405cd6SLois Curfman McInnes if (!(it % 2)) { 67008405cd6SLois Curfman McInnes [compute Jacobian here] 67108405cd6SLois Curfman McInnes } 67208405cd6SLois Curfman McInnes .ve 673c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 67408405cd6SLois Curfman McInnes recomputed every second SNES iteration. 675c8228a4eSBarry Smith 67636851e7fSLois Curfman McInnes Level: intermediate 67736851e7fSLois Curfman McInnes 6782b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 6792b668275SBarry Smith 680b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 6819b94acceSBarry Smith @*/ 6827087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 6839b94acceSBarry Smith { 6843a40ed3dSBarry Smith PetscFunctionBegin; 6850700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 6864482741eSBarry Smith PetscValidIntPointer(iter,2); 6879b94acceSBarry Smith *iter = snes->iter; 6883a40ed3dSBarry Smith PetscFunctionReturn(0); 6899b94acceSBarry Smith } 69074679c65SBarry Smith 6914a2ae208SSatish Balay #undef __FUNCT__ 6924a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 6939b94acceSBarry Smith /*@ 6949b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 6959b94acceSBarry Smith with SNESSSetFunction(). 6969b94acceSBarry Smith 697c7afd0dbSLois Curfman McInnes Collective on SNES 698c7afd0dbSLois Curfman McInnes 6999b94acceSBarry Smith Input Parameter: 7009b94acceSBarry Smith . snes - SNES context 7019b94acceSBarry Smith 7029b94acceSBarry Smith Output Parameter: 7039b94acceSBarry Smith . fnorm - 2-norm of function 7049b94acceSBarry Smith 70536851e7fSLois Curfman McInnes Level: intermediate 70636851e7fSLois Curfman McInnes 7079b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 708a86d99e1SLois Curfman McInnes 709b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 7109b94acceSBarry Smith @*/ 7117087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 7129b94acceSBarry Smith { 7133a40ed3dSBarry Smith PetscFunctionBegin; 7140700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7154482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 7169b94acceSBarry Smith *fnorm = snes->norm; 7173a40ed3dSBarry Smith PetscFunctionReturn(0); 7189b94acceSBarry Smith } 71974679c65SBarry Smith 7204a2ae208SSatish Balay #undef __FUNCT__ 721b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 7229b94acceSBarry Smith /*@ 723b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 7249b94acceSBarry Smith attempted by the nonlinear solver. 7259b94acceSBarry Smith 726c7afd0dbSLois Curfman McInnes Not Collective 727c7afd0dbSLois Curfman McInnes 7289b94acceSBarry Smith Input Parameter: 7299b94acceSBarry Smith . snes - SNES context 7309b94acceSBarry Smith 7319b94acceSBarry Smith Output Parameter: 7329b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 7339b94acceSBarry Smith 734c96a6f78SLois Curfman McInnes Notes: 735c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 736c96a6f78SLois Curfman McInnes 73736851e7fSLois Curfman McInnes Level: intermediate 73836851e7fSLois Curfman McInnes 7399b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 74058ebbce7SBarry Smith 741e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 74258ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 7439b94acceSBarry Smith @*/ 7447087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 7459b94acceSBarry Smith { 7463a40ed3dSBarry Smith PetscFunctionBegin; 7470700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7484482741eSBarry Smith PetscValidIntPointer(nfails,2); 74950ffb88aSMatthew Knepley *nfails = snes->numFailures; 75050ffb88aSMatthew Knepley PetscFunctionReturn(0); 75150ffb88aSMatthew Knepley } 75250ffb88aSMatthew Knepley 75350ffb88aSMatthew Knepley #undef __FUNCT__ 754b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 75550ffb88aSMatthew Knepley /*@ 756b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 75750ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 75850ffb88aSMatthew Knepley 75950ffb88aSMatthew Knepley Not Collective 76050ffb88aSMatthew Knepley 76150ffb88aSMatthew Knepley Input Parameters: 76250ffb88aSMatthew Knepley + snes - SNES context 76350ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 76450ffb88aSMatthew Knepley 76550ffb88aSMatthew Knepley Level: intermediate 76650ffb88aSMatthew Knepley 76750ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 76858ebbce7SBarry Smith 769e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 77058ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 77150ffb88aSMatthew Knepley @*/ 7727087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 77350ffb88aSMatthew Knepley { 77450ffb88aSMatthew Knepley PetscFunctionBegin; 7750700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 77650ffb88aSMatthew Knepley snes->maxFailures = maxFails; 77750ffb88aSMatthew Knepley PetscFunctionReturn(0); 77850ffb88aSMatthew Knepley } 77950ffb88aSMatthew Knepley 78050ffb88aSMatthew Knepley #undef __FUNCT__ 781b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 78250ffb88aSMatthew Knepley /*@ 783b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 78450ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 78550ffb88aSMatthew Knepley 78650ffb88aSMatthew Knepley Not Collective 78750ffb88aSMatthew Knepley 78850ffb88aSMatthew Knepley Input Parameter: 78950ffb88aSMatthew Knepley . snes - SNES context 79050ffb88aSMatthew Knepley 79150ffb88aSMatthew Knepley Output Parameter: 79250ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 79350ffb88aSMatthew Knepley 79450ffb88aSMatthew Knepley Level: intermediate 79550ffb88aSMatthew Knepley 79650ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 79758ebbce7SBarry Smith 798e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 79958ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 80058ebbce7SBarry Smith 80150ffb88aSMatthew Knepley @*/ 8027087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 80350ffb88aSMatthew Knepley { 80450ffb88aSMatthew Knepley PetscFunctionBegin; 8050700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8064482741eSBarry Smith PetscValidIntPointer(maxFails,2); 80750ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 8083a40ed3dSBarry Smith PetscFunctionReturn(0); 8099b94acceSBarry Smith } 810a847f771SSatish Balay 8114a2ae208SSatish Balay #undef __FUNCT__ 8122541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 8132541af92SBarry Smith /*@ 8142541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 8152541af92SBarry Smith done by SNES. 8162541af92SBarry Smith 8172541af92SBarry Smith Not Collective 8182541af92SBarry Smith 8192541af92SBarry Smith Input Parameter: 8202541af92SBarry Smith . snes - SNES context 8212541af92SBarry Smith 8222541af92SBarry Smith Output Parameter: 8232541af92SBarry Smith . nfuncs - number of evaluations 8242541af92SBarry Smith 8252541af92SBarry Smith Level: intermediate 8262541af92SBarry Smith 8272541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 82858ebbce7SBarry Smith 829e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 8302541af92SBarry Smith @*/ 8317087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 8322541af92SBarry Smith { 8332541af92SBarry Smith PetscFunctionBegin; 8340700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8352541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 8362541af92SBarry Smith *nfuncs = snes->nfuncs; 8372541af92SBarry Smith PetscFunctionReturn(0); 8382541af92SBarry Smith } 8392541af92SBarry Smith 8402541af92SBarry Smith #undef __FUNCT__ 8413d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 8423d4c4710SBarry Smith /*@ 8433d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 8443d4c4710SBarry Smith linear solvers. 8453d4c4710SBarry Smith 8463d4c4710SBarry Smith Not Collective 8473d4c4710SBarry Smith 8483d4c4710SBarry Smith Input Parameter: 8493d4c4710SBarry Smith . snes - SNES context 8503d4c4710SBarry Smith 8513d4c4710SBarry Smith Output Parameter: 8523d4c4710SBarry Smith . nfails - number of failed solves 8533d4c4710SBarry Smith 8543d4c4710SBarry Smith Notes: 8553d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 8563d4c4710SBarry Smith 8573d4c4710SBarry Smith Level: intermediate 8583d4c4710SBarry Smith 8593d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 86058ebbce7SBarry Smith 861e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 8623d4c4710SBarry Smith @*/ 8637087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 8643d4c4710SBarry Smith { 8653d4c4710SBarry Smith PetscFunctionBegin; 8660700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8673d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 8683d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 8693d4c4710SBarry Smith PetscFunctionReturn(0); 8703d4c4710SBarry Smith } 8713d4c4710SBarry Smith 8723d4c4710SBarry Smith #undef __FUNCT__ 8733d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 8743d4c4710SBarry Smith /*@ 8753d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 8763d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 8773d4c4710SBarry Smith 8783f9fe445SBarry Smith Logically Collective on SNES 8793d4c4710SBarry Smith 8803d4c4710SBarry Smith Input Parameters: 8813d4c4710SBarry Smith + snes - SNES context 8823d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 8833d4c4710SBarry Smith 8843d4c4710SBarry Smith Level: intermediate 8853d4c4710SBarry Smith 886a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 8873d4c4710SBarry Smith 8883d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 8893d4c4710SBarry Smith 89058ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 8913d4c4710SBarry Smith @*/ 8927087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 8933d4c4710SBarry Smith { 8943d4c4710SBarry Smith PetscFunctionBegin; 8950700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 896c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 8973d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 8983d4c4710SBarry Smith PetscFunctionReturn(0); 8993d4c4710SBarry Smith } 9003d4c4710SBarry Smith 9013d4c4710SBarry Smith #undef __FUNCT__ 9023d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 9033d4c4710SBarry Smith /*@ 9043d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 9053d4c4710SBarry Smith are allowed before SNES terminates 9063d4c4710SBarry Smith 9073d4c4710SBarry Smith Not Collective 9083d4c4710SBarry Smith 9093d4c4710SBarry Smith Input Parameter: 9103d4c4710SBarry Smith . snes - SNES context 9113d4c4710SBarry Smith 9123d4c4710SBarry Smith Output Parameter: 9133d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 9143d4c4710SBarry Smith 9153d4c4710SBarry Smith Level: intermediate 9163d4c4710SBarry Smith 9173d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 9183d4c4710SBarry Smith 9193d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 9203d4c4710SBarry Smith 921e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 9223d4c4710SBarry Smith @*/ 9237087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 9243d4c4710SBarry Smith { 9253d4c4710SBarry Smith PetscFunctionBegin; 9260700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9273d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 9283d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 9293d4c4710SBarry Smith PetscFunctionReturn(0); 9303d4c4710SBarry Smith } 9313d4c4710SBarry Smith 9323d4c4710SBarry Smith #undef __FUNCT__ 933b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 934c96a6f78SLois Curfman McInnes /*@ 935b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 936c96a6f78SLois Curfman McInnes used by the nonlinear solver. 937c96a6f78SLois Curfman McInnes 938c7afd0dbSLois Curfman McInnes Not Collective 939c7afd0dbSLois Curfman McInnes 940c96a6f78SLois Curfman McInnes Input Parameter: 941c96a6f78SLois Curfman McInnes . snes - SNES context 942c96a6f78SLois Curfman McInnes 943c96a6f78SLois Curfman McInnes Output Parameter: 944c96a6f78SLois Curfman McInnes . lits - number of linear iterations 945c96a6f78SLois Curfman McInnes 946c96a6f78SLois Curfman McInnes Notes: 947c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 948c96a6f78SLois Curfman McInnes 94936851e7fSLois Curfman McInnes Level: intermediate 95036851e7fSLois Curfman McInnes 951c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 9522b668275SBarry Smith 9538c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 954c96a6f78SLois Curfman McInnes @*/ 9557087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 956c96a6f78SLois Curfman McInnes { 9573a40ed3dSBarry Smith PetscFunctionBegin; 9580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9594482741eSBarry Smith PetscValidIntPointer(lits,2); 960c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 9613a40ed3dSBarry Smith PetscFunctionReturn(0); 962c96a6f78SLois Curfman McInnes } 963c96a6f78SLois Curfman McInnes 9644a2ae208SSatish Balay #undef __FUNCT__ 96594b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 96652baeb72SSatish Balay /*@ 96794b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 9689b94acceSBarry Smith 96994b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 970c7afd0dbSLois Curfman McInnes 9719b94acceSBarry Smith Input Parameter: 9729b94acceSBarry Smith . snes - the SNES context 9739b94acceSBarry Smith 9749b94acceSBarry Smith Output Parameter: 97594b7f48cSBarry Smith . ksp - the KSP context 9769b94acceSBarry Smith 9779b94acceSBarry Smith Notes: 97894b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 9799b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 9802999313aSBarry Smith PC contexts as well. 9819b94acceSBarry Smith 98236851e7fSLois Curfman McInnes Level: beginner 98336851e7fSLois Curfman McInnes 98494b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 9859b94acceSBarry Smith 9862999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 9879b94acceSBarry Smith @*/ 9887087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 9899b94acceSBarry Smith { 9901cee3971SBarry Smith PetscErrorCode ierr; 9911cee3971SBarry Smith 9923a40ed3dSBarry Smith PetscFunctionBegin; 9930700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9944482741eSBarry Smith PetscValidPointer(ksp,2); 9951cee3971SBarry Smith 9961cee3971SBarry Smith if (!snes->ksp) { 9971cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 9981cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 9991cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 10001cee3971SBarry Smith } 100194b7f48cSBarry Smith *ksp = snes->ksp; 10023a40ed3dSBarry Smith PetscFunctionReturn(0); 10039b94acceSBarry Smith } 100482bf6240SBarry Smith 10054a2ae208SSatish Balay #undef __FUNCT__ 10062999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 10072999313aSBarry Smith /*@ 10082999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 10092999313aSBarry Smith 10102999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 10112999313aSBarry Smith 10122999313aSBarry Smith Input Parameters: 10132999313aSBarry Smith + snes - the SNES context 10142999313aSBarry Smith - ksp - the KSP context 10152999313aSBarry Smith 10162999313aSBarry Smith Notes: 10172999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 10182999313aSBarry Smith so this routine is rarely needed. 10192999313aSBarry Smith 10202999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 10212999313aSBarry Smith decreased by one. 10222999313aSBarry Smith 10232999313aSBarry Smith Level: developer 10242999313aSBarry Smith 10252999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 10262999313aSBarry Smith 10272999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 10282999313aSBarry Smith @*/ 10297087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 10302999313aSBarry Smith { 10312999313aSBarry Smith PetscErrorCode ierr; 10322999313aSBarry Smith 10332999313aSBarry Smith PetscFunctionBegin; 10340700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10350700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 10362999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 10377dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1038906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 10392999313aSBarry Smith snes->ksp = ksp; 10402999313aSBarry Smith PetscFunctionReturn(0); 10412999313aSBarry Smith } 10422999313aSBarry Smith 10437adad957SLisandro Dalcin #if 0 10442999313aSBarry Smith #undef __FUNCT__ 10454a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 10466849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1047e24b481bSBarry Smith { 1048e24b481bSBarry Smith PetscFunctionBegin; 1049e24b481bSBarry Smith PetscFunctionReturn(0); 1050e24b481bSBarry Smith } 10517adad957SLisandro Dalcin #endif 1052e24b481bSBarry Smith 10539b94acceSBarry Smith /* -----------------------------------------------------------*/ 10544a2ae208SSatish Balay #undef __FUNCT__ 10554a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 105652baeb72SSatish Balay /*@ 10579b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 10589b94acceSBarry Smith 1059c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1060c7afd0dbSLois Curfman McInnes 1061c7afd0dbSLois Curfman McInnes Input Parameters: 1062906ed7ccSBarry Smith . comm - MPI communicator 10639b94acceSBarry Smith 10649b94acceSBarry Smith Output Parameter: 10659b94acceSBarry Smith . outsnes - the new SNES context 10669b94acceSBarry Smith 1067c7afd0dbSLois Curfman McInnes Options Database Keys: 1068c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1069c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1070c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1071c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1072c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1073c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1074c1f60f51SBarry Smith 107536851e7fSLois Curfman McInnes Level: beginner 107636851e7fSLois Curfman McInnes 10779b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 10789b94acceSBarry Smith 1079a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1080a8054027SBarry Smith 10819b94acceSBarry Smith @*/ 10827087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 10839b94acceSBarry Smith { 1084dfbe8321SBarry Smith PetscErrorCode ierr; 10859b94acceSBarry Smith SNES snes; 1086fa9f3622SBarry Smith SNESKSPEW *kctx; 108737fcc0dbSBarry Smith 10883a40ed3dSBarry Smith PetscFunctionBegin; 1089ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 10908ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 10918ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 10928ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 10938ba1e511SMatthew Knepley #endif 10948ba1e511SMatthew Knepley 10953194b578SJed Brown ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 10967adad957SLisandro Dalcin 109785385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 10982c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 1099d28543b3SPeter Brune snes->usegs = PETSC_FALSE; 11009b94acceSBarry Smith snes->max_its = 50; 11019750a799SBarry Smith snes->max_funcs = 10000; 11029b94acceSBarry Smith snes->norm = 0.0; 1103b4874afaSBarry Smith snes->rtol = 1.e-8; 1104b4874afaSBarry Smith snes->ttol = 0.0; 110570441072SBarry Smith snes->abstol = 1.e-50; 11069b94acceSBarry Smith snes->xtol = 1.e-8; 11074b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 11089b94acceSBarry Smith snes->nfuncs = 0; 110950ffb88aSMatthew Knepley snes->numFailures = 0; 111050ffb88aSMatthew Knepley snes->maxFailures = 1; 11117a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1112e35cf81dSBarry Smith snes->lagjacobian = 1; 1113a8054027SBarry Smith snes->lagpreconditioner = 1; 1114639f9d9dSBarry Smith snes->numbermonitors = 0; 11159b94acceSBarry Smith snes->data = 0; 11164dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1117186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 11186f24a144SLois Curfman McInnes snes->nwork = 0; 111958c9b817SLisandro Dalcin snes->work = 0; 112058c9b817SLisandro Dalcin snes->nvwork = 0; 112158c9b817SLisandro Dalcin snes->vwork = 0; 1122758f92a0SBarry Smith snes->conv_hist_len = 0; 1123758f92a0SBarry Smith snes->conv_hist_max = 0; 1124758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1125758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1126758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1127184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 112889b92e6fSPeter Brune snes->gssweeps = 1; 11299b94acceSBarry Smith 1130ea630c6eSPeter Brune /* initialize the line search options */ 1131ea630c6eSPeter Brune snes->ls_type = SNES_LS_BASIC; 1132af60355fSPeter Brune snes->ls_its = 1; 1133ea630c6eSPeter Brune snes->damping = 1.0; 1134ea630c6eSPeter Brune snes->maxstep = 1e8; 1135ea630c6eSPeter Brune snes->steptol = 1e-12; 1136ea630c6eSPeter Brune snes->ls_alpha = 1e-4; 1137ea630c6eSPeter Brune snes->ls_monitor = PETSC_NULL; 1138ea630c6eSPeter Brune 1139ea630c6eSPeter Brune snes->ops->linesearch = PETSC_NULL; 1140ea630c6eSPeter Brune snes->precheck = PETSC_NULL; 1141ea630c6eSPeter Brune snes->ops->precheckstep = PETSC_NULL; 1142ea630c6eSPeter Brune snes->postcheck = PETSC_NULL; 1143ea630c6eSPeter Brune snes->ops->postcheckstep= PETSC_NULL; 1144ea630c6eSPeter Brune 11453d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 11463d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 11473d4c4710SBarry Smith 11489b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 114938f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 11509b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 11519b94acceSBarry Smith kctx->version = 2; 11529b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 11539b94acceSBarry Smith this was too large for some test cases */ 115475567043SBarry Smith kctx->rtol_last = 0.0; 11559b94acceSBarry Smith kctx->rtol_max = .9; 11569b94acceSBarry Smith kctx->gamma = 1.0; 115762d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 115871f87433Sdalcinl kctx->alpha2 = kctx->alpha; 11599b94acceSBarry Smith kctx->threshold = .1; 116075567043SBarry Smith kctx->lresid_last = 0.0; 116175567043SBarry Smith kctx->norm_last = 0.0; 11629b94acceSBarry Smith 11639b94acceSBarry Smith *outsnes = snes; 11643a40ed3dSBarry Smith PetscFunctionReturn(0); 11659b94acceSBarry Smith } 11669b94acceSBarry Smith 11674a2ae208SSatish Balay #undef __FUNCT__ 11684a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 11699b94acceSBarry Smith /*@C 11709b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 11719b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 11729b94acceSBarry Smith equations. 11739b94acceSBarry Smith 11743f9fe445SBarry Smith Logically Collective on SNES 1175fee21e36SBarry Smith 1176c7afd0dbSLois Curfman McInnes Input Parameters: 1177c7afd0dbSLois Curfman McInnes + snes - the SNES context 1178c7afd0dbSLois Curfman McInnes . r - vector to store function value 1179de044059SHong Zhang . func - function evaluation routine 1180c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1181c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 11829b94acceSBarry Smith 1183c7afd0dbSLois Curfman McInnes Calling sequence of func: 11848d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1185c7afd0dbSLois Curfman McInnes 1186313e4042SLois Curfman McInnes . f - function vector 1187c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 11889b94acceSBarry Smith 11899b94acceSBarry Smith Notes: 11909b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 11919b94acceSBarry Smith $ f'(x) x = -f(x), 1192c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 11939b94acceSBarry Smith 119436851e7fSLois Curfman McInnes Level: beginner 119536851e7fSLois Curfman McInnes 11969b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 11979b94acceSBarry Smith 11988b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard() 11999b94acceSBarry Smith @*/ 12007087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 12019b94acceSBarry Smith { 120285385478SLisandro Dalcin PetscErrorCode ierr; 12033a40ed3dSBarry Smith PetscFunctionBegin; 12040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1205d2a683ecSLisandro Dalcin if (r) { 1206d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1207d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 120885385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 12096bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 121085385478SLisandro Dalcin snes->vec_func = r; 1211d2a683ecSLisandro Dalcin } else if (!snes->vec_func && snes->dm) { 1212d2a683ecSLisandro Dalcin ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 1213d2a683ecSLisandro Dalcin } 1214d2a683ecSLisandro Dalcin if (func) snes->ops->computefunction = func; 1215d2a683ecSLisandro Dalcin if (ctx) snes->funP = ctx; 12163a40ed3dSBarry Smith PetscFunctionReturn(0); 12179b94acceSBarry Smith } 12189b94acceSBarry Smith 1219646217ecSPeter Brune 1220646217ecSPeter Brune #undef __FUNCT__ 1221646217ecSPeter Brune #define __FUNCT__ "SNESSetGS" 1222c79ef259SPeter Brune /*@C 1223c79ef259SPeter Brune SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for 1224c79ef259SPeter Brune use with composed nonlinear solvers. 1225c79ef259SPeter Brune 1226c79ef259SPeter Brune Input Parameters: 1227c79ef259SPeter Brune + snes - the SNES context 1228c79ef259SPeter Brune . gsfunc - function evaluation routine 1229c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 1230c79ef259SPeter Brune smoother evaluation routine (may be PETSC_NULL) 1231c79ef259SPeter Brune 1232c79ef259SPeter Brune Calling sequence of func: 1233c79ef259SPeter Brune $ func (SNES snes,Vec x,Vec b,void *ctx); 1234c79ef259SPeter Brune 1235c79ef259SPeter Brune + X - solution vector 1236c79ef259SPeter Brune . B - RHS vector 1237d28543b3SPeter Brune - ctx - optional user-defined Gauss-Seidel context 1238c79ef259SPeter Brune 1239c79ef259SPeter Brune Notes: 1240c79ef259SPeter Brune The GS routines are used by the composed nonlinear solver to generate 1241c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1242c79ef259SPeter Brune 1243d28543b3SPeter Brune Level: intermediate 1244c79ef259SPeter Brune 1245d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1246c79ef259SPeter Brune 1247c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS() 1248c79ef259SPeter Brune @*/ 1249646217ecSPeter Brune PetscErrorCode SNESSetGS(SNES snes, PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void *), void * ctx) { 1250646217ecSPeter Brune PetscFunctionBegin; 1251646217ecSPeter Brune if (gsfunc) snes->ops->computegs = gsfunc; 1252646217ecSPeter Brune if (ctx) snes->gsP = ctx; 1253646217ecSPeter Brune PetscFunctionReturn(0); 1254646217ecSPeter Brune } 1255646217ecSPeter Brune 1256d25893d9SBarry Smith #undef __FUNCT__ 1257d28543b3SPeter Brune #define __FUNCT__ "SNESSetUseGS" 1258d28543b3SPeter Brune /*@ 1259d28543b3SPeter Brune SNESSetUseGS - Toggles use of the user-set nonlinear GS solver in 1260d28543b3SPeter Brune SNES solvers that may use a preconditioning routine. 1261d28543b3SPeter Brune 1262d28543b3SPeter Brune Input Parameters: 1263d28543b3SPeter Brune + snes - the SNES context 1264d28543b3SPeter Brune - usegs - whether to use the nonlinear GS routine or not. 1265d28543b3SPeter Brune 1266d28543b3SPeter Brune Notes: 1267d28543b3SPeter Brune The behavior of the nonlinear GS solvers is that if useGS is set, then 1268d28543b3SPeter Brune the update is constructed with the user-defined nonlinear GS method. 1269d28543b3SPeter Brune Otherwise, the update is either formed by the user-customized 1270d28543b3SPeter Brune preconditioner SNES, or by nonlinear richardson if both of these 1271d28543b3SPeter Brune are not provided. 1272d28543b3SPeter Brune 1273d28543b3SPeter Brune Level: intermediate 1274d28543b3SPeter Brune 1275d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 1276d28543b3SPeter Brune 1277d28543b3SPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetUseGS() 1278d28543b3SPeter Brune @*/ 1279d28543b3SPeter Brune PetscErrorCode SNESSetUseGS(SNES snes, PetscBool usegs) { 1280d28543b3SPeter Brune PetscFunctionBegin; 1281d28543b3SPeter Brune snes->usegs = usegs; 1282d28543b3SPeter Brune PetscFunctionReturn(0); 1283d28543b3SPeter Brune } 1284d28543b3SPeter Brune 1285d28543b3SPeter Brune 1286d28543b3SPeter Brune #undef __FUNCT__ 1287d28543b3SPeter Brune #define __FUNCT__ "SNESGetUseGS" 1288d28543b3SPeter Brune /*@ 1289d28543b3SPeter Brune SNESGetUseGS - Returns whether or not the SNES is using a 1290d28543b3SPeter Brune provided nonlinear GS routine. 1291d28543b3SPeter Brune 1292d28543b3SPeter Brune Input Parameters: 1293d28543b3SPeter Brune + snes - the SNES context 1294d28543b3SPeter Brune - usegs - flag indicating whether or not GS is being used 1295d28543b3SPeter Brune 1296d28543b3SPeter Brune Level: intermediate 1297d28543b3SPeter Brune 1298d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1299d28543b3SPeter Brune 1300d28543b3SPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetUseGS() 1301d28543b3SPeter Brune @*/ 1302d28543b3SPeter Brune 1303d28543b3SPeter Brune PetscErrorCode SNESGetUseGS(SNES snes, PetscBool * usegs) { 1304d28543b3SPeter Brune PetscFunctionBegin; 1305d28543b3SPeter Brune 1306d28543b3SPeter Brune *usegs = snes->usegs; 1307d28543b3SPeter Brune PetscFunctionReturn(0); 1308d28543b3SPeter Brune } 1309d28543b3SPeter Brune 1310d28543b3SPeter Brune #undef __FUNCT__ 131189b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps" 131289b92e6fSPeter Brune /*@ 131389b92e6fSPeter Brune SNESSetGSSweeps - Sets the number of sweeps of GS to use. 131489b92e6fSPeter Brune 131589b92e6fSPeter Brune Input Parameters: 131689b92e6fSPeter Brune + snes - the SNES context 131789b92e6fSPeter Brune - sweeps - the number of sweeps of GS to perform. 131889b92e6fSPeter Brune 131989b92e6fSPeter Brune Level: intermediate 132089b92e6fSPeter Brune 132189b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 132289b92e6fSPeter Brune 132389b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps() 132489b92e6fSPeter Brune @*/ 132589b92e6fSPeter Brune 132689b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) { 132789b92e6fSPeter Brune PetscFunctionBegin; 132889b92e6fSPeter Brune snes->gssweeps = sweeps; 132989b92e6fSPeter Brune PetscFunctionReturn(0); 133089b92e6fSPeter Brune } 133189b92e6fSPeter Brune 133289b92e6fSPeter Brune 133389b92e6fSPeter Brune #undef __FUNCT__ 133489b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps" 133589b92e6fSPeter Brune /*@ 133689b92e6fSPeter Brune SNESGetGSSweeps - Gets the number of sweeps GS will use. 133789b92e6fSPeter Brune 133889b92e6fSPeter Brune Input Parameters: 133989b92e6fSPeter Brune . snes - the SNES context 134089b92e6fSPeter Brune 134189b92e6fSPeter Brune Output Parameters: 134289b92e6fSPeter Brune . sweeps - the number of sweeps of GS to perform. 134389b92e6fSPeter Brune 134489b92e6fSPeter Brune Level: intermediate 134589b92e6fSPeter Brune 134689b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 134789b92e6fSPeter Brune 134889b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps() 134989b92e6fSPeter Brune @*/ 135089b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) { 135189b92e6fSPeter Brune PetscFunctionBegin; 135289b92e6fSPeter Brune *sweeps = snes->gssweeps; 135389b92e6fSPeter Brune PetscFunctionReturn(0); 135489b92e6fSPeter Brune } 135589b92e6fSPeter Brune 135689b92e6fSPeter Brune #undef __FUNCT__ 13578b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 13588b0a5094SBarry Smith PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 13598b0a5094SBarry Smith { 13608b0a5094SBarry Smith PetscErrorCode ierr; 13618b0a5094SBarry Smith PetscFunctionBegin; 13628b0a5094SBarry Smith /* A(x)*x - b(x) */ 13638b0a5094SBarry Smith ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,snes->jacP);CHKERRQ(ierr); 13648b0a5094SBarry Smith ierr = (*snes->ops->computepfunction)(snes,x,f,snes->funP);CHKERRQ(ierr); 13658b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 13668b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 13678b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 13688b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 13698b0a5094SBarry Smith PetscFunctionReturn(0); 13708b0a5094SBarry Smith } 13718b0a5094SBarry Smith 13728b0a5094SBarry Smith #undef __FUNCT__ 13738b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 13748b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 13758b0a5094SBarry Smith { 13768b0a5094SBarry Smith PetscFunctionBegin; 13778b0a5094SBarry Smith *flag = snes->matstruct; 13788b0a5094SBarry Smith PetscFunctionReturn(0); 13798b0a5094SBarry Smith } 13808b0a5094SBarry Smith 13818b0a5094SBarry Smith #undef __FUNCT__ 13828b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 13838b0a5094SBarry Smith /*@C 13840d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 13858b0a5094SBarry Smith 13868b0a5094SBarry Smith Logically Collective on SNES 13878b0a5094SBarry Smith 13888b0a5094SBarry Smith Input Parameters: 13898b0a5094SBarry Smith + snes - the SNES context 13908b0a5094SBarry Smith . r - vector to store function value 13918b0a5094SBarry Smith . func - function evaluation routine 13928b0a5094SBarry Smith . jmat - normally the same as mat but you can pass another matrix for which you compute the Jacobian of A(x) x - b(x) (see jmat below) 13938b0a5094SBarry Smith . mat - matrix to store A 13948b0a5094SBarry Smith . mfunc - function to compute matrix value 13958b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 13968b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 13978b0a5094SBarry Smith 13988b0a5094SBarry Smith Calling sequence of func: 13998b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 14008b0a5094SBarry Smith 14018b0a5094SBarry Smith + f - function vector 14028b0a5094SBarry Smith - ctx - optional user-defined function context 14038b0a5094SBarry Smith 14048b0a5094SBarry Smith Calling sequence of mfunc: 14058b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 14068b0a5094SBarry Smith 14078b0a5094SBarry Smith + x - input vector 14088b0a5094SBarry Smith . jmat - Form Jacobian matrix of A(x) x - b(x) if available, not there is really no reason to use it in this way since then you can just use SNESSetJacobian(), 14098b0a5094SBarry Smith normally just pass mat in this location 14108b0a5094SBarry Smith . mat - form A(x) matrix 14118b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 14128b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 14138b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 14148b0a5094SBarry Smith 14158b0a5094SBarry Smith Notes: 14168b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 14178b0a5094SBarry Smith 14188b0a5094SBarry Smith $ Solves the equation A(x) x = b(x) via the defect correction algorithm A(x^{n}) (x^{n+1} - x^{n}) = b(x^{n}) - A(x^{n})x^{n} 14198b0a5094SBarry Smith $ Note that when an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = b(x^{n}) iteration. 14208b0a5094SBarry Smith 14218b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 14228b0a5094SBarry Smith 14230d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 14240d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 14258b0a5094SBarry Smith 14268b0a5094SBarry Smith There is some controversity over the definition of a Picard iteration for nonlinear systems but almost everyone agrees that it involves a linear solve and some 14278b0a5094SBarry Smith believe it is the iteration A(x^{n}) x^{n+1} = b(x^{n}) hence we use the name Picard. If anyone has an authoritative reference that defines the Picard iteration 14288b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 14298b0a5094SBarry Smith 14308b0a5094SBarry Smith Level: beginner 14318b0a5094SBarry Smith 14328b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 14338b0a5094SBarry Smith 14340d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard() 14358b0a5094SBarry Smith @*/ 14368b0a5094SBarry Smith PetscErrorCode SNESSetPicard(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),Mat jmat, Mat mat, PetscErrorCode (*mfunc)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 14378b0a5094SBarry Smith { 14388b0a5094SBarry Smith PetscErrorCode ierr; 14398b0a5094SBarry Smith PetscFunctionBegin; 14408b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14418b0a5094SBarry Smith snes->ops->computepfunction = func; 14428b0a5094SBarry Smith snes->ops->computepjacobian = mfunc; 14438b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 14448b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 14458b0a5094SBarry Smith PetscFunctionReturn(0); 14468b0a5094SBarry Smith } 14478b0a5094SBarry Smith 14488b0a5094SBarry Smith #undef __FUNCT__ 1449d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1450d25893d9SBarry Smith /*@C 1451d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1452d25893d9SBarry Smith 1453d25893d9SBarry Smith Logically Collective on SNES 1454d25893d9SBarry Smith 1455d25893d9SBarry Smith Input Parameters: 1456d25893d9SBarry Smith + snes - the SNES context 1457d25893d9SBarry Smith . func - function evaluation routine 1458d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1459d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1460d25893d9SBarry Smith 1461d25893d9SBarry Smith Calling sequence of func: 1462d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1463d25893d9SBarry Smith 1464d25893d9SBarry Smith . f - function vector 1465d25893d9SBarry Smith - ctx - optional user-defined function context 1466d25893d9SBarry Smith 1467d25893d9SBarry Smith Level: intermediate 1468d25893d9SBarry Smith 1469d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1470d25893d9SBarry Smith 1471d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1472d25893d9SBarry Smith @*/ 1473d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1474d25893d9SBarry Smith { 1475d25893d9SBarry Smith PetscFunctionBegin; 1476d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1477d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1478d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1479d25893d9SBarry Smith PetscFunctionReturn(0); 1480d25893d9SBarry Smith } 1481d25893d9SBarry Smith 14823ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 14833ab0aad5SBarry Smith #undef __FUNCT__ 14841096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 14851096aae1SMatthew Knepley /*@C 14861096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 14871096aae1SMatthew Knepley it assumes a zero right hand side. 14881096aae1SMatthew Knepley 14893f9fe445SBarry Smith Logically Collective on SNES 14901096aae1SMatthew Knepley 14911096aae1SMatthew Knepley Input Parameter: 14921096aae1SMatthew Knepley . snes - the SNES context 14931096aae1SMatthew Knepley 14941096aae1SMatthew Knepley Output Parameter: 1495bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 14961096aae1SMatthew Knepley 14971096aae1SMatthew Knepley Level: intermediate 14981096aae1SMatthew Knepley 14991096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 15001096aae1SMatthew Knepley 150185385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 15021096aae1SMatthew Knepley @*/ 15037087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 15041096aae1SMatthew Knepley { 15051096aae1SMatthew Knepley PetscFunctionBegin; 15060700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15071096aae1SMatthew Knepley PetscValidPointer(rhs,2); 150885385478SLisandro Dalcin *rhs = snes->vec_rhs; 15091096aae1SMatthew Knepley PetscFunctionReturn(0); 15101096aae1SMatthew Knepley } 15111096aae1SMatthew Knepley 15121096aae1SMatthew Knepley #undef __FUNCT__ 15134a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 15149b94acceSBarry Smith /*@ 151536851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 15169b94acceSBarry Smith SNESSetFunction(). 15179b94acceSBarry Smith 1518c7afd0dbSLois Curfman McInnes Collective on SNES 1519c7afd0dbSLois Curfman McInnes 15209b94acceSBarry Smith Input Parameters: 1521c7afd0dbSLois Curfman McInnes + snes - the SNES context 1522c7afd0dbSLois Curfman McInnes - x - input vector 15239b94acceSBarry Smith 15249b94acceSBarry Smith Output Parameter: 15253638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 15269b94acceSBarry Smith 15271bffabb2SLois Curfman McInnes Notes: 152836851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 152936851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 153036851e7fSLois Curfman McInnes themselves. 153136851e7fSLois Curfman McInnes 153236851e7fSLois Curfman McInnes Level: developer 153336851e7fSLois Curfman McInnes 15349b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 15359b94acceSBarry Smith 1536a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 15379b94acceSBarry Smith @*/ 15387087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 15399b94acceSBarry Smith { 1540dfbe8321SBarry Smith PetscErrorCode ierr; 15419b94acceSBarry Smith 15423a40ed3dSBarry Smith PetscFunctionBegin; 15430700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15440700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 15450700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1546c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1547c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 15484ec14c9cSBarry Smith VecValidValues(x,2,PETSC_TRUE); 1549184914b5SBarry Smith 1550d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 1551e7788613SBarry Smith if (snes->ops->computefunction) { 1552d64ed03dSBarry Smith PetscStackPush("SNES user function"); 155339d508bbSBarry Smith ierr = (*snes->ops->computefunction)(snes,x,y,snes->funP);CHKERRQ(ierr); 1554d64ed03dSBarry Smith PetscStackPop; 155573250ac0SBarry Smith } else if (snes->dm) { 1556644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1557c90fad12SPeter Brune } else if (snes->vec_rhs) { 1558c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1559644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 156085385478SLisandro Dalcin if (snes->vec_rhs) { 156185385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 15623ab0aad5SBarry Smith } 1563ae3c334cSLois Curfman McInnes snes->nfuncs++; 1564d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 15654ec14c9cSBarry Smith VecValidValues(y,3,PETSC_FALSE); 15663a40ed3dSBarry Smith PetscFunctionReturn(0); 15679b94acceSBarry Smith } 15689b94acceSBarry Smith 15694a2ae208SSatish Balay #undef __FUNCT__ 1570646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1571c79ef259SPeter Brune /*@ 1572c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1573c79ef259SPeter Brune SNESSetGS(). 1574c79ef259SPeter Brune 1575c79ef259SPeter Brune Collective on SNES 1576c79ef259SPeter Brune 1577c79ef259SPeter Brune Input Parameters: 1578c79ef259SPeter Brune + snes - the SNES context 1579c79ef259SPeter Brune . x - input vector 1580c79ef259SPeter Brune - b - rhs vector 1581c79ef259SPeter Brune 1582c79ef259SPeter Brune Output Parameter: 1583c79ef259SPeter Brune . x - new solution vector 1584c79ef259SPeter Brune 1585c79ef259SPeter Brune Notes: 1586c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1587c79ef259SPeter Brune implementations, so most users would not generally call this routine 1588c79ef259SPeter Brune themselves. 1589c79ef259SPeter Brune 1590c79ef259SPeter Brune Level: developer 1591c79ef259SPeter Brune 1592c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1593c79ef259SPeter Brune 1594c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1595c79ef259SPeter Brune @*/ 1596646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1597646217ecSPeter Brune { 1598646217ecSPeter Brune PetscErrorCode ierr; 159989b92e6fSPeter Brune PetscInt i; 1600646217ecSPeter Brune 1601646217ecSPeter Brune PetscFunctionBegin; 1602646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1603646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1604646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1605646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 1606646217ecSPeter Brune if(b) PetscCheckSameComm(snes,1,b,3); 16074ec14c9cSBarry Smith if (b) VecValidValues(b,2,PETSC_TRUE); 1608701cf23dSPeter Brune ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 1609646217ecSPeter Brune if (snes->ops->computegs) { 161089b92e6fSPeter Brune for (i = 0; i < snes->gssweeps; i++) { 1611646217ecSPeter Brune PetscStackPush("SNES user GS"); 1612646217ecSPeter Brune ierr = (*snes->ops->computegs)(snes,x,b,snes->gsP);CHKERRQ(ierr); 1613646217ecSPeter Brune PetscStackPop; 161489b92e6fSPeter Brune } 1615646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 1616701cf23dSPeter Brune ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 16174ec14c9cSBarry Smith VecValidValues(x,3,PETSC_FALSE); 1618646217ecSPeter Brune PetscFunctionReturn(0); 1619646217ecSPeter Brune } 1620646217ecSPeter Brune 1621646217ecSPeter Brune 1622646217ecSPeter Brune #undef __FUNCT__ 16234a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 162462fef451SLois Curfman McInnes /*@ 162562fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 162662fef451SLois Curfman McInnes set with SNESSetJacobian(). 162762fef451SLois Curfman McInnes 1628c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1629c7afd0dbSLois Curfman McInnes 163062fef451SLois Curfman McInnes Input Parameters: 1631c7afd0dbSLois Curfman McInnes + snes - the SNES context 1632c7afd0dbSLois Curfman McInnes - x - input vector 163362fef451SLois Curfman McInnes 163462fef451SLois Curfman McInnes Output Parameters: 1635c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 163662fef451SLois Curfman McInnes . B - optional preconditioning matrix 16372b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1638fee21e36SBarry Smith 1639e35cf81dSBarry Smith Options Database Keys: 1640e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1641693365a8SJed Brown . -snes_lag_jacobian <lag> 1642693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1643693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1644693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 16454c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1646c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 1647c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 1648c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 1649c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 1650c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 16514c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 1652c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 1653c01495d3SJed Brown 1654e35cf81dSBarry Smith 165562fef451SLois Curfman McInnes Notes: 165662fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 165762fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 165862fef451SLois Curfman McInnes 165994b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1660dc5a77f8SLois Curfman McInnes flag parameter. 166162fef451SLois Curfman McInnes 166236851e7fSLois Curfman McInnes Level: developer 166336851e7fSLois Curfman McInnes 166462fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 166562fef451SLois Curfman McInnes 1666e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 166762fef451SLois Curfman McInnes @*/ 16687087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 16699b94acceSBarry Smith { 1670dfbe8321SBarry Smith PetscErrorCode ierr; 1671ace3abfcSBarry Smith PetscBool flag; 16723a40ed3dSBarry Smith 16733a40ed3dSBarry Smith PetscFunctionBegin; 16740700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16750700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 16764482741eSBarry Smith PetscValidPointer(flg,5); 1677c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 16784ec14c9cSBarry Smith VecValidValues(X,2,PETSC_TRUE); 1679e7788613SBarry Smith if (!snes->ops->computejacobian) PetscFunctionReturn(0); 1680ebd3b9afSBarry Smith 1681ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1682ebd3b9afSBarry Smith 1683fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 1684fe3ffe1eSBarry Smith snes->lagjacobian = -1; 1685fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1686fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 1687e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1688e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1689ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1690ebd3b9afSBarry Smith if (flag) { 1691ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1692ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1693ebd3b9afSBarry Smith } 1694e35cf81dSBarry Smith PetscFunctionReturn(0); 1695e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1696e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1697e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1698ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1699ebd3b9afSBarry Smith if (flag) { 1700ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1701ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1702ebd3b9afSBarry Smith } 1703e35cf81dSBarry Smith PetscFunctionReturn(0); 1704e35cf81dSBarry Smith } 1705e35cf81dSBarry Smith 1706c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 1707e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1708d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 1709e7788613SBarry Smith ierr = (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);CHKERRQ(ierr); 1710d64ed03dSBarry Smith PetscStackPop; 1711d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1712a8054027SBarry Smith 17133b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 17143b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 17153b4f5425SBarry Smith snes->lagpreconditioner = -1; 17163b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 1717a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1718a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 1719a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 1720a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1721a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 1722a8054027SBarry Smith } 1723a8054027SBarry Smith 17246d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 17250700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 17260700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 1727693365a8SJed Brown { 1728693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 1729693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 1730693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 1731693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 1732693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 1733693365a8SJed Brown if (flag || flag_draw || flag_contour) { 1734693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 1735693365a8SJed Brown MatStructure mstruct; 1736693365a8SJed Brown PetscViewer vdraw,vstdout; 17376b3a5b13SJed Brown PetscBool flg; 1738693365a8SJed Brown if (flag_operator) { 1739693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 1740693365a8SJed Brown Bexp = Bexp_mine; 1741693365a8SJed Brown } else { 1742693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 1743693365a8SJed Brown ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 1744693365a8SJed Brown if (flg) Bexp = *B; 1745693365a8SJed Brown else { 1746693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 1747693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 1748693365a8SJed Brown Bexp = Bexp_mine; 1749693365a8SJed Brown } 1750693365a8SJed Brown } 1751693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 1752693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 1753693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 1754693365a8SJed Brown if (flag_draw || flag_contour) { 1755693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 1756693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 1757693365a8SJed Brown } else vdraw = PETSC_NULL; 1758693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 1759693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 1760693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 1761693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 1762693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1763693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 1764693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1765693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 1766693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1767693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 1768693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 1769693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 1770693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 1771693365a8SJed Brown } 1772693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 1773693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 1774693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 1775693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 1776693365a8SJed Brown } 1777693365a8SJed Brown } 17784c30e9fbSJed Brown { 17796719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 17806719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 17814c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 17826719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 17834c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 17844c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 17856719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 17866719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 17876719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 17886719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 17894c30e9fbSJed Brown Mat Bfd; 17904c30e9fbSJed Brown MatStructure mstruct; 17914c30e9fbSJed Brown PetscViewer vdraw,vstdout; 17924c30e9fbSJed Brown ISColoring iscoloring; 17934c30e9fbSJed Brown MatFDColoring matfdcoloring; 17944c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 17954c30e9fbSJed Brown void *funcctx; 17966719d8e4SJed Brown PetscReal norm1,norm2,normmax; 17974c30e9fbSJed Brown 17984c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 17994c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 18004c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 18014c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 18024c30e9fbSJed Brown 18034c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 18044c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 18054c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 18064c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 18074c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 18084c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 18094c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 18104c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 18114c30e9fbSJed Brown 18124c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 18134c30e9fbSJed Brown if (flag_draw || flag_contour) { 18144c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 18154c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 18164c30e9fbSJed Brown } else vdraw = PETSC_NULL; 18174c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 18186719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 18194c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 18204c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 18216719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 18224c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 18234c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 18244c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 18256719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 18264c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 18276719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 18286719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 18294c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 18304c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 18314c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 18324c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 18334c30e9fbSJed Brown } 18344c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 18356719d8e4SJed Brown 18366719d8e4SJed Brown if (flag_threshold) { 18376719d8e4SJed Brown PetscInt bs,rstart,rend,i; 18386719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 18396719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 18406719d8e4SJed Brown for (i=rstart; i<rend; i++) { 18416719d8e4SJed Brown const PetscScalar *ba,*ca; 18426719d8e4SJed Brown const PetscInt *bj,*cj; 18436719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 18446719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 18456719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 18466719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 18476719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 18486719d8e4SJed Brown for (j=0; j<bn; j++) { 18496719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 18506719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 18516719d8e4SJed Brown maxentrycol = bj[j]; 18526719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 18536719d8e4SJed Brown } 18546719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 18556719d8e4SJed Brown maxdiffcol = bj[j]; 18566719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 18576719d8e4SJed Brown } 18586719d8e4SJed Brown if (rdiff > maxrdiff) { 18596719d8e4SJed Brown maxrdiffcol = bj[j]; 18606719d8e4SJed Brown maxrdiff = rdiff; 18616719d8e4SJed Brown } 18626719d8e4SJed Brown } 18636719d8e4SJed Brown if (maxrdiff > 1) { 18646719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"row %D (maxentry=%G at %D, maxdiff=%G at %D, maxrdiff=%G at %D):",i,maxentry,maxentrycol,maxdiff,maxdiffcol,maxrdiff,maxrdiffcol);CHKERRQ(ierr); 18656719d8e4SJed Brown for (j=0; j<bn; j++) { 18666719d8e4SJed Brown PetscReal rdiff; 18676719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 18686719d8e4SJed Brown if (rdiff > 1) { 18696719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 18706719d8e4SJed Brown } 18716719d8e4SJed Brown } 18726719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 18736719d8e4SJed Brown } 18746719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 18756719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 18766719d8e4SJed Brown } 18776719d8e4SJed Brown } 18784c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 18794c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 18804c30e9fbSJed Brown } 18814c30e9fbSJed Brown } 18823a40ed3dSBarry Smith PetscFunctionReturn(0); 18839b94acceSBarry Smith } 18849b94acceSBarry Smith 18854a2ae208SSatish Balay #undef __FUNCT__ 18864a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 18879b94acceSBarry Smith /*@C 18889b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 1889044dda88SLois Curfman McInnes location to store the matrix. 18909b94acceSBarry Smith 18913f9fe445SBarry Smith Logically Collective on SNES and Mat 1892c7afd0dbSLois Curfman McInnes 18939b94acceSBarry Smith Input Parameters: 1894c7afd0dbSLois Curfman McInnes + snes - the SNES context 18959b94acceSBarry Smith . A - Jacobian matrix 18969b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 1897efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 1898c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1899efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 19009b94acceSBarry Smith 19019b94acceSBarry Smith Calling sequence of func: 19028d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 19039b94acceSBarry Smith 1904c7afd0dbSLois Curfman McInnes + x - input vector 19059b94acceSBarry Smith . A - Jacobian matrix 19069b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 1907ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 19082b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 1909c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 19109b94acceSBarry Smith 19119b94acceSBarry Smith Notes: 191294b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 19132cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 1914ac21db08SLois Curfman McInnes 1915ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 19169b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 19179b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 19189b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 19199b94acceSBarry Smith throughout the global iterations. 19209b94acceSBarry Smith 192116913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 192216913363SBarry Smith each matrix. 192316913363SBarry Smith 1924a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 1925a8a26c1eSJed Brown must be a MatFDColoring. 1926a8a26c1eSJed Brown 1927c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 1928c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 1929c3cc8fd1SJed Brown 193036851e7fSLois Curfman McInnes Level: beginner 193136851e7fSLois Curfman McInnes 19329b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 19339b94acceSBarry Smith 19343ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 19359b94acceSBarry Smith @*/ 19367087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 19379b94acceSBarry Smith { 1938dfbe8321SBarry Smith PetscErrorCode ierr; 19393a7fca6bSBarry Smith 19403a40ed3dSBarry Smith PetscFunctionBegin; 19410700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 19420700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 19430700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 1944c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 194506975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 1946e7788613SBarry Smith if (func) snes->ops->computejacobian = func; 19473a7fca6bSBarry Smith if (ctx) snes->jacP = ctx; 19483a7fca6bSBarry Smith if (A) { 19497dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 19506bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 19519b94acceSBarry Smith snes->jacobian = A; 19523a7fca6bSBarry Smith } 19533a7fca6bSBarry Smith if (B) { 19547dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 19556bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 19569b94acceSBarry Smith snes->jacobian_pre = B; 19573a7fca6bSBarry Smith } 19583a40ed3dSBarry Smith PetscFunctionReturn(0); 19599b94acceSBarry Smith } 196062fef451SLois Curfman McInnes 19614a2ae208SSatish Balay #undef __FUNCT__ 19624a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 1963c2aafc4cSSatish Balay /*@C 1964b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 1965b4fd4287SBarry Smith provided context for evaluating the Jacobian. 1966b4fd4287SBarry Smith 1967c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 1968c7afd0dbSLois Curfman McInnes 1969b4fd4287SBarry Smith Input Parameter: 1970b4fd4287SBarry Smith . snes - the nonlinear solver context 1971b4fd4287SBarry Smith 1972b4fd4287SBarry Smith Output Parameters: 1973c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 1974b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 197570e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 197670e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 1977fee21e36SBarry Smith 197836851e7fSLois Curfman McInnes Level: advanced 197936851e7fSLois Curfman McInnes 1980b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 1981b4fd4287SBarry Smith @*/ 19827087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 1983b4fd4287SBarry Smith { 19843a40ed3dSBarry Smith PetscFunctionBegin; 19850700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1986b4fd4287SBarry Smith if (A) *A = snes->jacobian; 1987b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 1988e7788613SBarry Smith if (func) *func = snes->ops->computejacobian; 198970e92668SMatthew Knepley if (ctx) *ctx = snes->jacP; 19903a40ed3dSBarry Smith PetscFunctionReturn(0); 1991b4fd4287SBarry Smith } 1992b4fd4287SBarry Smith 19939b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 19949b94acceSBarry Smith 19954a2ae208SSatish Balay #undef __FUNCT__ 19964a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 19979b94acceSBarry Smith /*@ 19989b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 1999272ac6f2SLois Curfman McInnes of a nonlinear solver. 20009b94acceSBarry Smith 2001fee21e36SBarry Smith Collective on SNES 2002fee21e36SBarry Smith 2003c7afd0dbSLois Curfman McInnes Input Parameters: 200470e92668SMatthew Knepley . snes - the SNES context 2005c7afd0dbSLois Curfman McInnes 2006272ac6f2SLois Curfman McInnes Notes: 2007272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2008272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2009272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2010272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2011272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2012272ac6f2SLois Curfman McInnes 201336851e7fSLois Curfman McInnes Level: advanced 201436851e7fSLois Curfman McInnes 20159b94acceSBarry Smith .keywords: SNES, nonlinear, setup 20169b94acceSBarry Smith 20179b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 20189b94acceSBarry Smith @*/ 20197087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 20209b94acceSBarry Smith { 2021dfbe8321SBarry Smith PetscErrorCode ierr; 20223a40ed3dSBarry Smith 20233a40ed3dSBarry Smith PetscFunctionBegin; 20240700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 20254dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 20269b94acceSBarry Smith 20277adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 202885385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 202985385478SLisandro Dalcin } 203085385478SLisandro Dalcin 2031a63bb30eSJed Brown ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 203217186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 203358c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 203458c9b817SLisandro Dalcin 203558c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 203658c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 203758c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 203858c9b817SLisandro Dalcin } 203958c9b817SLisandro Dalcin 2040ef8dffc7SBarry Smith if (!snes->ops->computejacobian && snes->dm) { 2041214df951SJed Brown Mat J,B; 2042214df951SJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 2043214df951SJed Brown if (snes->mf_operator) { 2044214df951SJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 2045214df951SJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 2046214df951SJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 2047214df951SJed Brown } else { 2048214df951SJed Brown J = B; 2049214df951SJed Brown ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr); 2050214df951SJed Brown } 2051214df951SJed Brown ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr); 2052cab2e9ccSBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 2053214df951SJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 20542ef29e96SBarry Smith } else if (!snes->jacobian && snes->ops->computejacobian == MatMFFDComputeJacobian) { 2055a8248277SBarry Smith Mat J; 2056a8248277SBarry Smith ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 2057a8248277SBarry Smith ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 2058a8248277SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 2059a8248277SBarry Smith ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);CHKERRQ(ierr); 2060a8248277SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 2061a8248277SBarry Smith } else if (snes->dm && snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 2062a8248277SBarry Smith Mat J,B; 2063a8248277SBarry Smith ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 2064a8248277SBarry Smith ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 2065a8248277SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 2066950540a4SJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 2067a8248277SBarry Smith ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,snes->funP);CHKERRQ(ierr); 2068a8248277SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 2069a8248277SBarry Smith ierr = MatDestroy(&B);CHKERRQ(ierr); 2070efd51863SBarry Smith } else if (snes->dm && !snes->jacobian_pre){ 2071efd51863SBarry Smith Mat J; 2072950540a4SJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr); 20733cbb28f5SBarry Smith ierr = SNESSetJacobian(snes,J,J,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 2074efd51863SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 2075ef8dffc7SBarry Smith } 2076cfaf3a74SBarry Smith if (!snes->ops->computefunction && !snes->dm) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction() or call SNESSetDM()"); 2077c9b9fda1SJed Brown if (!snes->vec_func) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a vector when calling SNESSetFunction() or call SNESSetDM()"); 2078efd51863SBarry Smith 2079b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 2080b710008aSBarry Smith 2081d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 2082d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2083d25893d9SBarry Smith } 2084d25893d9SBarry Smith 2085410397dcSLisandro Dalcin if (snes->ops->setup) { 2086410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2087410397dcSLisandro Dalcin } 208858c9b817SLisandro Dalcin 20897aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 20903a40ed3dSBarry Smith PetscFunctionReturn(0); 20919b94acceSBarry Smith } 20929b94acceSBarry Smith 20934a2ae208SSatish Balay #undef __FUNCT__ 209437596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 209537596af1SLisandro Dalcin /*@ 209637596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 209737596af1SLisandro Dalcin 209837596af1SLisandro Dalcin Collective on SNES 209937596af1SLisandro Dalcin 210037596af1SLisandro Dalcin Input Parameter: 210137596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 210237596af1SLisandro Dalcin 2103d25893d9SBarry Smith Level: intermediate 2104d25893d9SBarry Smith 2105d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 210637596af1SLisandro Dalcin 210737596af1SLisandro Dalcin .keywords: SNES, destroy 210837596af1SLisandro Dalcin 210937596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 211037596af1SLisandro Dalcin @*/ 211137596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 211237596af1SLisandro Dalcin { 211337596af1SLisandro Dalcin PetscErrorCode ierr; 211437596af1SLisandro Dalcin 211537596af1SLisandro Dalcin PetscFunctionBegin; 211637596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2117d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2118d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2119d25893d9SBarry Smith snes->user = PETSC_NULL; 2120d25893d9SBarry Smith } 21218a23116dSBarry Smith if (snes->pc) { 21228a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 21238a23116dSBarry Smith } 21248a23116dSBarry Smith 212537596af1SLisandro Dalcin if (snes->ops->reset) { 212637596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 212737596af1SLisandro Dalcin } 212837596af1SLisandro Dalcin if (snes->ksp) {ierr = KSPReset(snes->ksp);CHKERRQ(ierr);} 21296bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 21306bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 21316bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 21326bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 21336bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 21346bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 213537596af1SLisandro Dalcin if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);} 213637596af1SLisandro Dalcin if (snes->vwork) {ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);} 213737596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 213837596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 213937596af1SLisandro Dalcin PetscFunctionReturn(0); 214037596af1SLisandro Dalcin } 214137596af1SLisandro Dalcin 214237596af1SLisandro Dalcin #undef __FUNCT__ 21434a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 214452baeb72SSatish Balay /*@ 21459b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 21469b94acceSBarry Smith with SNESCreate(). 21479b94acceSBarry Smith 2148c7afd0dbSLois Curfman McInnes Collective on SNES 2149c7afd0dbSLois Curfman McInnes 21509b94acceSBarry Smith Input Parameter: 21519b94acceSBarry Smith . snes - the SNES context 21529b94acceSBarry Smith 215336851e7fSLois Curfman McInnes Level: beginner 215436851e7fSLois Curfman McInnes 21559b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 21569b94acceSBarry Smith 215763a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 21589b94acceSBarry Smith @*/ 21596bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 21609b94acceSBarry Smith { 21616849ba73SBarry Smith PetscErrorCode ierr; 21623a40ed3dSBarry Smith 21633a40ed3dSBarry Smith PetscFunctionBegin; 21646bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 21656bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 21666bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2167d4bb536fSBarry Smith 21686bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 21698a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 21706b8b9a38SLisandro Dalcin 2171be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 21726bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 21736bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 21746d4c513bSLisandro Dalcin 21756bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 21766bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 21776b8b9a38SLisandro Dalcin 21786bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 21796bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 21806bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 21816b8b9a38SLisandro Dalcin } 21826bf464f9SBarry Smith if ((*snes)->conv_malloc) { 21836bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 21846bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 218558c9b817SLisandro Dalcin } 2186ea630c6eSPeter Brune ierr = PetscViewerDestroy(&(*snes)->ls_monitor);CHKERRQ(ierr); 21876bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2188a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 21893a40ed3dSBarry Smith PetscFunctionReturn(0); 21909b94acceSBarry Smith } 21919b94acceSBarry Smith 21929b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 21939b94acceSBarry Smith 21944a2ae208SSatish Balay #undef __FUNCT__ 2195a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2196a8054027SBarry Smith /*@ 2197a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2198a8054027SBarry Smith 21993f9fe445SBarry Smith Logically Collective on SNES 2200a8054027SBarry Smith 2201a8054027SBarry Smith Input Parameters: 2202a8054027SBarry Smith + snes - the SNES context 2203a8054027SBarry 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 22043b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2205a8054027SBarry Smith 2206a8054027SBarry Smith Options Database Keys: 2207a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2208a8054027SBarry Smith 2209a8054027SBarry Smith Notes: 2210a8054027SBarry Smith The default is 1 2211a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2212a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2213a8054027SBarry Smith 2214a8054027SBarry Smith Level: intermediate 2215a8054027SBarry Smith 2216a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2217a8054027SBarry Smith 2218e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2219a8054027SBarry Smith 2220a8054027SBarry Smith @*/ 22217087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2222a8054027SBarry Smith { 2223a8054027SBarry Smith PetscFunctionBegin; 22240700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2225e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2226e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2227c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2228a8054027SBarry Smith snes->lagpreconditioner = lag; 2229a8054027SBarry Smith PetscFunctionReturn(0); 2230a8054027SBarry Smith } 2231a8054027SBarry Smith 2232a8054027SBarry Smith #undef __FUNCT__ 2233efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2234efd51863SBarry Smith /*@ 2235efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2236efd51863SBarry Smith 2237efd51863SBarry Smith Logically Collective on SNES 2238efd51863SBarry Smith 2239efd51863SBarry Smith Input Parameters: 2240efd51863SBarry Smith + snes - the SNES context 2241efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2242efd51863SBarry Smith 2243efd51863SBarry Smith Options Database Keys: 2244efd51863SBarry Smith . -snes_grid_sequence <steps> 2245efd51863SBarry Smith 2246efd51863SBarry Smith Level: intermediate 2247efd51863SBarry Smith 2248c0df2a02SJed Brown Notes: 2249c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2250c0df2a02SJed Brown 2251efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2252efd51863SBarry Smith 2253efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2254efd51863SBarry Smith 2255efd51863SBarry Smith @*/ 2256efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2257efd51863SBarry Smith { 2258efd51863SBarry Smith PetscFunctionBegin; 2259efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2260efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2261efd51863SBarry Smith snes->gridsequence = steps; 2262efd51863SBarry Smith PetscFunctionReturn(0); 2263efd51863SBarry Smith } 2264efd51863SBarry Smith 2265efd51863SBarry Smith #undef __FUNCT__ 2266a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2267a8054027SBarry Smith /*@ 2268a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2269a8054027SBarry Smith 22703f9fe445SBarry Smith Not Collective 2271a8054027SBarry Smith 2272a8054027SBarry Smith Input Parameter: 2273a8054027SBarry Smith . snes - the SNES context 2274a8054027SBarry Smith 2275a8054027SBarry Smith Output Parameter: 2276a8054027SBarry 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 22773b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2278a8054027SBarry Smith 2279a8054027SBarry Smith Options Database Keys: 2280a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2281a8054027SBarry Smith 2282a8054027SBarry Smith Notes: 2283a8054027SBarry Smith The default is 1 2284a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2285a8054027SBarry Smith 2286a8054027SBarry Smith Level: intermediate 2287a8054027SBarry Smith 2288a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2289a8054027SBarry Smith 2290a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2291a8054027SBarry Smith 2292a8054027SBarry Smith @*/ 22937087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2294a8054027SBarry Smith { 2295a8054027SBarry Smith PetscFunctionBegin; 22960700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2297a8054027SBarry Smith *lag = snes->lagpreconditioner; 2298a8054027SBarry Smith PetscFunctionReturn(0); 2299a8054027SBarry Smith } 2300a8054027SBarry Smith 2301a8054027SBarry Smith #undef __FUNCT__ 2302e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2303e35cf81dSBarry Smith /*@ 2304e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2305e35cf81dSBarry Smith often the preconditioner is rebuilt. 2306e35cf81dSBarry Smith 23073f9fe445SBarry Smith Logically Collective on SNES 2308e35cf81dSBarry Smith 2309e35cf81dSBarry Smith Input Parameters: 2310e35cf81dSBarry Smith + snes - the SNES context 2311e35cf81dSBarry 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 2312fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2313e35cf81dSBarry Smith 2314e35cf81dSBarry Smith Options Database Keys: 2315e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2316e35cf81dSBarry Smith 2317e35cf81dSBarry Smith Notes: 2318e35cf81dSBarry Smith The default is 1 2319e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2320fe3ffe1eSBarry 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 2321fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2322e35cf81dSBarry Smith 2323e35cf81dSBarry Smith Level: intermediate 2324e35cf81dSBarry Smith 2325e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2326e35cf81dSBarry Smith 2327e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2328e35cf81dSBarry Smith 2329e35cf81dSBarry Smith @*/ 23307087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2331e35cf81dSBarry Smith { 2332e35cf81dSBarry Smith PetscFunctionBegin; 23330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2334e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2335e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2336c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2337e35cf81dSBarry Smith snes->lagjacobian = lag; 2338e35cf81dSBarry Smith PetscFunctionReturn(0); 2339e35cf81dSBarry Smith } 2340e35cf81dSBarry Smith 2341e35cf81dSBarry Smith #undef __FUNCT__ 2342e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2343e35cf81dSBarry Smith /*@ 2344e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2345e35cf81dSBarry Smith 23463f9fe445SBarry Smith Not Collective 2347e35cf81dSBarry Smith 2348e35cf81dSBarry Smith Input Parameter: 2349e35cf81dSBarry Smith . snes - the SNES context 2350e35cf81dSBarry Smith 2351e35cf81dSBarry Smith Output Parameter: 2352e35cf81dSBarry 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 2353e35cf81dSBarry Smith the Jacobian is built etc. 2354e35cf81dSBarry Smith 2355e35cf81dSBarry Smith Options Database Keys: 2356e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2357e35cf81dSBarry Smith 2358e35cf81dSBarry Smith Notes: 2359e35cf81dSBarry Smith The default is 1 2360e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2361e35cf81dSBarry Smith 2362e35cf81dSBarry Smith Level: intermediate 2363e35cf81dSBarry Smith 2364e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2365e35cf81dSBarry Smith 2366e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2367e35cf81dSBarry Smith 2368e35cf81dSBarry Smith @*/ 23697087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2370e35cf81dSBarry Smith { 2371e35cf81dSBarry Smith PetscFunctionBegin; 23720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2373e35cf81dSBarry Smith *lag = snes->lagjacobian; 2374e35cf81dSBarry Smith PetscFunctionReturn(0); 2375e35cf81dSBarry Smith } 2376e35cf81dSBarry Smith 2377e35cf81dSBarry Smith #undef __FUNCT__ 23784a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 23799b94acceSBarry Smith /*@ 2380d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 23819b94acceSBarry Smith 23823f9fe445SBarry Smith Logically Collective on SNES 2383c7afd0dbSLois Curfman McInnes 23849b94acceSBarry Smith Input Parameters: 2385c7afd0dbSLois Curfman McInnes + snes - the SNES context 238670441072SBarry Smith . abstol - absolute convergence tolerance 238733174efeSLois Curfman McInnes . rtol - relative convergence tolerance 238833174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 238933174efeSLois Curfman McInnes of the change in the solution between steps 239033174efeSLois Curfman McInnes . maxit - maximum number of iterations 2391c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2392fee21e36SBarry Smith 239333174efeSLois Curfman McInnes Options Database Keys: 239470441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2395c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2396c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2397c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2398c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 23999b94acceSBarry Smith 2400d7a720efSLois Curfman McInnes Notes: 24019b94acceSBarry Smith The default maximum number of iterations is 50. 24029b94acceSBarry Smith The default maximum number of function evaluations is 1000. 24039b94acceSBarry Smith 240436851e7fSLois Curfman McInnes Level: intermediate 240536851e7fSLois Curfman McInnes 240633174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 24079b94acceSBarry Smith 24082492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 24099b94acceSBarry Smith @*/ 24107087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 24119b94acceSBarry Smith { 24123a40ed3dSBarry Smith PetscFunctionBegin; 24130700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2414c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2415c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2416c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2417c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2418c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2419c5eb9154SBarry Smith 2420ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2421ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2422ab54825eSJed Brown snes->abstol = abstol; 2423ab54825eSJed Brown } 2424ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2425ab54825eSJed Brown if (rtol < 0.0 || 1.0 <= rtol) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Relative tolerance %G must be non-negative and less than 1.0",rtol); 2426ab54825eSJed Brown snes->rtol = rtol; 2427ab54825eSJed Brown } 2428ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2429ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2430ab54825eSJed Brown snes->xtol = stol; 2431ab54825eSJed Brown } 2432ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2433ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2434ab54825eSJed Brown snes->max_its = maxit; 2435ab54825eSJed Brown } 2436ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2437ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2438ab54825eSJed Brown snes->max_funcs = maxf; 2439ab54825eSJed Brown } 24403a40ed3dSBarry Smith PetscFunctionReturn(0); 24419b94acceSBarry Smith } 24429b94acceSBarry Smith 24434a2ae208SSatish Balay #undef __FUNCT__ 24444a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 24459b94acceSBarry Smith /*@ 244633174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 244733174efeSLois Curfman McInnes 2448c7afd0dbSLois Curfman McInnes Not Collective 2449c7afd0dbSLois Curfman McInnes 245033174efeSLois Curfman McInnes Input Parameters: 2451c7afd0dbSLois Curfman McInnes + snes - the SNES context 245285385478SLisandro Dalcin . atol - absolute convergence tolerance 245333174efeSLois Curfman McInnes . rtol - relative convergence tolerance 245433174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 245533174efeSLois Curfman McInnes of the change in the solution between steps 245633174efeSLois Curfman McInnes . maxit - maximum number of iterations 2457c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2458fee21e36SBarry Smith 245933174efeSLois Curfman McInnes Notes: 246033174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 246133174efeSLois Curfman McInnes 246236851e7fSLois Curfman McInnes Level: intermediate 246336851e7fSLois Curfman McInnes 246433174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 246533174efeSLois Curfman McInnes 246633174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 246733174efeSLois Curfman McInnes @*/ 24687087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 246933174efeSLois Curfman McInnes { 24703a40ed3dSBarry Smith PetscFunctionBegin; 24710700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 247285385478SLisandro Dalcin if (atol) *atol = snes->abstol; 247333174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 247433174efeSLois Curfman McInnes if (stol) *stol = snes->xtol; 247533174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 247633174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 24773a40ed3dSBarry Smith PetscFunctionReturn(0); 247833174efeSLois Curfman McInnes } 247933174efeSLois Curfman McInnes 24804a2ae208SSatish Balay #undef __FUNCT__ 24814a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 248233174efeSLois Curfman McInnes /*@ 24839b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 24849b94acceSBarry Smith 24853f9fe445SBarry Smith Logically Collective on SNES 2486fee21e36SBarry Smith 2487c7afd0dbSLois Curfman McInnes Input Parameters: 2488c7afd0dbSLois Curfman McInnes + snes - the SNES context 2489c7afd0dbSLois Curfman McInnes - tol - tolerance 2490c7afd0dbSLois Curfman McInnes 24919b94acceSBarry Smith Options Database Key: 2492c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 24939b94acceSBarry Smith 249436851e7fSLois Curfman McInnes Level: intermediate 249536851e7fSLois Curfman McInnes 24969b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 24979b94acceSBarry Smith 24982492ecdbSBarry Smith .seealso: SNESSetTolerances() 24999b94acceSBarry Smith @*/ 25007087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 25019b94acceSBarry Smith { 25023a40ed3dSBarry Smith PetscFunctionBegin; 25030700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2504c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 25059b94acceSBarry Smith snes->deltatol = tol; 25063a40ed3dSBarry Smith PetscFunctionReturn(0); 25079b94acceSBarry Smith } 25089b94acceSBarry Smith 2509df9fa365SBarry Smith /* 2510df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2511df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2512df9fa365SBarry Smith macros instead of functions 2513df9fa365SBarry Smith */ 25144a2ae208SSatish Balay #undef __FUNCT__ 2515a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 25167087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2517ce1608b8SBarry Smith { 2518dfbe8321SBarry Smith PetscErrorCode ierr; 2519ce1608b8SBarry Smith 2520ce1608b8SBarry Smith PetscFunctionBegin; 25210700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2522a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2523ce1608b8SBarry Smith PetscFunctionReturn(0); 2524ce1608b8SBarry Smith } 2525ce1608b8SBarry Smith 25264a2ae208SSatish Balay #undef __FUNCT__ 2527a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 25287087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2529df9fa365SBarry Smith { 2530dfbe8321SBarry Smith PetscErrorCode ierr; 2531df9fa365SBarry Smith 2532df9fa365SBarry Smith PetscFunctionBegin; 2533a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2534df9fa365SBarry Smith PetscFunctionReturn(0); 2535df9fa365SBarry Smith } 2536df9fa365SBarry Smith 25374a2ae208SSatish Balay #undef __FUNCT__ 2538a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 25396bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2540df9fa365SBarry Smith { 2541dfbe8321SBarry Smith PetscErrorCode ierr; 2542df9fa365SBarry Smith 2543df9fa365SBarry Smith PetscFunctionBegin; 2544a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2545df9fa365SBarry Smith PetscFunctionReturn(0); 2546df9fa365SBarry Smith } 2547df9fa365SBarry Smith 25487087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2549b271bb04SBarry Smith #undef __FUNCT__ 2550b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 25517087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2552b271bb04SBarry Smith { 2553b271bb04SBarry Smith PetscDrawLG lg; 2554b271bb04SBarry Smith PetscErrorCode ierr; 2555b271bb04SBarry Smith PetscReal x,y,per; 2556b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2557b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2558b271bb04SBarry Smith PetscDraw draw; 2559b271bb04SBarry Smith PetscFunctionBegin; 2560b271bb04SBarry Smith if (!monctx) { 2561b271bb04SBarry Smith MPI_Comm comm; 2562b271bb04SBarry Smith 2563b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2564b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2565b271bb04SBarry Smith } 2566b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2567b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2568b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2569b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2570b271bb04SBarry Smith x = (PetscReal) n; 2571b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2572b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2573b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2574b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2575b271bb04SBarry Smith } 2576b271bb04SBarry Smith 2577b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2578b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2579b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2580b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2581b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2582b271bb04SBarry Smith x = (PetscReal) n; 2583b271bb04SBarry Smith y = 100.0*per; 2584b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2585b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2586b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2587b271bb04SBarry Smith } 2588b271bb04SBarry Smith 2589b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2590b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2591b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2592b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2593b271bb04SBarry Smith x = (PetscReal) n; 2594b271bb04SBarry Smith y = (prev - rnorm)/prev; 2595b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2596b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2597b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2598b271bb04SBarry Smith } 2599b271bb04SBarry Smith 2600b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2601b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2602b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2603b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2604b271bb04SBarry Smith x = (PetscReal) n; 2605b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2606b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2607b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2608b271bb04SBarry Smith } 2609b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2610b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2611b271bb04SBarry Smith } 2612b271bb04SBarry Smith prev = rnorm; 2613b271bb04SBarry Smith PetscFunctionReturn(0); 2614b271bb04SBarry Smith } 2615b271bb04SBarry Smith 2616b271bb04SBarry Smith #undef __FUNCT__ 2617b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 26187087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2619b271bb04SBarry Smith { 2620b271bb04SBarry Smith PetscErrorCode ierr; 2621b271bb04SBarry Smith 2622b271bb04SBarry Smith PetscFunctionBegin; 2623b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2624b271bb04SBarry Smith PetscFunctionReturn(0); 2625b271bb04SBarry Smith } 2626b271bb04SBarry Smith 2627b271bb04SBarry Smith #undef __FUNCT__ 2628b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 26296bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2630b271bb04SBarry Smith { 2631b271bb04SBarry Smith PetscErrorCode ierr; 2632b271bb04SBarry Smith 2633b271bb04SBarry Smith PetscFunctionBegin; 2634b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2635b271bb04SBarry Smith PetscFunctionReturn(0); 2636b271bb04SBarry Smith } 2637b271bb04SBarry Smith 26387a03ce2fSLisandro Dalcin #undef __FUNCT__ 26397a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 2640228d79bcSJed Brown /*@ 2641228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 2642228d79bcSJed Brown 2643228d79bcSJed Brown Collective on SNES 2644228d79bcSJed Brown 2645228d79bcSJed Brown Input Parameters: 2646228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 2647228d79bcSJed Brown . iter - iteration number 2648228d79bcSJed Brown - rnorm - relative norm of the residual 2649228d79bcSJed Brown 2650228d79bcSJed Brown Notes: 2651228d79bcSJed Brown This routine is called by the SNES implementations. 2652228d79bcSJed Brown It does not typically need to be called by the user. 2653228d79bcSJed Brown 2654228d79bcSJed Brown Level: developer 2655228d79bcSJed Brown 2656228d79bcSJed Brown .seealso: SNESMonitorSet() 2657228d79bcSJed Brown @*/ 26587a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 26597a03ce2fSLisandro Dalcin { 26607a03ce2fSLisandro Dalcin PetscErrorCode ierr; 26617a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 26627a03ce2fSLisandro Dalcin 26637a03ce2fSLisandro Dalcin PetscFunctionBegin; 26647a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 26657a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 26667a03ce2fSLisandro Dalcin } 26677a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 26687a03ce2fSLisandro Dalcin } 26697a03ce2fSLisandro Dalcin 26709b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 26719b94acceSBarry Smith 26724a2ae208SSatish Balay #undef __FUNCT__ 2673a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 26749b94acceSBarry Smith /*@C 2675a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 26769b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 26779b94acceSBarry Smith progress. 26789b94acceSBarry Smith 26793f9fe445SBarry Smith Logically Collective on SNES 2680fee21e36SBarry Smith 2681c7afd0dbSLois Curfman McInnes Input Parameters: 2682c7afd0dbSLois Curfman McInnes + snes - the SNES context 2683c7afd0dbSLois Curfman McInnes . func - monitoring routine 2684b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 2685e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 2686b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 2687b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 26889b94acceSBarry Smith 2689c7afd0dbSLois Curfman McInnes Calling sequence of func: 2690a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2691c7afd0dbSLois Curfman McInnes 2692c7afd0dbSLois Curfman McInnes + snes - the SNES context 2693c7afd0dbSLois Curfman McInnes . its - iteration number 2694c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 269540a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 26969b94acceSBarry Smith 26979665c990SLois Curfman McInnes Options Database Keys: 2698a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 2699a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 2700a6570f20SBarry Smith uses SNESMonitorLGCreate() 2701cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 2702c7afd0dbSLois Curfman McInnes been hardwired into a code by 2703a6570f20SBarry Smith calls to SNESMonitorSet(), but 2704c7afd0dbSLois Curfman McInnes does not cancel those set via 2705c7afd0dbSLois Curfman McInnes the options database. 27069665c990SLois Curfman McInnes 2707639f9d9dSBarry Smith Notes: 27086bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 2709a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 27106bc08f3fSLois Curfman McInnes order in which they were set. 2711639f9d9dSBarry Smith 2712025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 2713025f1a04SBarry Smith 271436851e7fSLois Curfman McInnes Level: intermediate 271536851e7fSLois Curfman McInnes 27169b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 27179b94acceSBarry Smith 2718a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 27199b94acceSBarry Smith @*/ 2720c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 27219b94acceSBarry Smith { 2722b90d0a6eSBarry Smith PetscInt i; 2723649052a6SBarry Smith PetscErrorCode ierr; 2724b90d0a6eSBarry Smith 27253a40ed3dSBarry Smith PetscFunctionBegin; 27260700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 272717186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2728b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 2729649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 2730649052a6SBarry Smith if (monitordestroy) { 2731c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 2732649052a6SBarry Smith } 2733b90d0a6eSBarry Smith PetscFunctionReturn(0); 2734b90d0a6eSBarry Smith } 2735b90d0a6eSBarry Smith } 2736b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 2737b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 2738639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 27393a40ed3dSBarry Smith PetscFunctionReturn(0); 27409b94acceSBarry Smith } 27419b94acceSBarry Smith 27424a2ae208SSatish Balay #undef __FUNCT__ 2743a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 27445cd90555SBarry Smith /*@C 2745a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 27465cd90555SBarry Smith 27473f9fe445SBarry Smith Logically Collective on SNES 2748c7afd0dbSLois Curfman McInnes 27495cd90555SBarry Smith Input Parameters: 27505cd90555SBarry Smith . snes - the SNES context 27515cd90555SBarry Smith 27521a480d89SAdministrator Options Database Key: 2753a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 2754a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 2755c7afd0dbSLois Curfman McInnes set via the options database 27565cd90555SBarry Smith 27575cd90555SBarry Smith Notes: 27585cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 27595cd90555SBarry Smith 276036851e7fSLois Curfman McInnes Level: intermediate 276136851e7fSLois Curfman McInnes 27625cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 27635cd90555SBarry Smith 2764a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 27655cd90555SBarry Smith @*/ 27667087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 27675cd90555SBarry Smith { 2768d952e501SBarry Smith PetscErrorCode ierr; 2769d952e501SBarry Smith PetscInt i; 2770d952e501SBarry Smith 27715cd90555SBarry Smith PetscFunctionBegin; 27720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2773d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 2774d952e501SBarry Smith if (snes->monitordestroy[i]) { 27753c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 2776d952e501SBarry Smith } 2777d952e501SBarry Smith } 27785cd90555SBarry Smith snes->numbermonitors = 0; 27795cd90555SBarry Smith PetscFunctionReturn(0); 27805cd90555SBarry Smith } 27815cd90555SBarry Smith 27824a2ae208SSatish Balay #undef __FUNCT__ 27834a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 27849b94acceSBarry Smith /*@C 27859b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 27869b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 27879b94acceSBarry Smith 27883f9fe445SBarry Smith Logically Collective on SNES 2789fee21e36SBarry Smith 2790c7afd0dbSLois Curfman McInnes Input Parameters: 2791c7afd0dbSLois Curfman McInnes + snes - the SNES context 2792c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 27937f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 27947f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 27959b94acceSBarry Smith 2796c7afd0dbSLois Curfman McInnes Calling sequence of func: 279706ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 2798c7afd0dbSLois Curfman McInnes 2799c7afd0dbSLois Curfman McInnes + snes - the SNES context 280006ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 2801c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 2802184914b5SBarry Smith . reason - reason for convergence/divergence 2803c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 28044b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 28054b27c08aSLois Curfman McInnes - f - 2-norm of function 28069b94acceSBarry Smith 280736851e7fSLois Curfman McInnes Level: advanced 280836851e7fSLois Curfman McInnes 28099b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 28109b94acceSBarry Smith 281185385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 28129b94acceSBarry Smith @*/ 28137087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 28149b94acceSBarry Smith { 28157f7931b9SBarry Smith PetscErrorCode ierr; 28167f7931b9SBarry Smith 28173a40ed3dSBarry Smith PetscFunctionBegin; 28180700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 281985385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 28207f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 28217f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 28227f7931b9SBarry Smith } 282385385478SLisandro Dalcin snes->ops->converged = func; 28247f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 282585385478SLisandro Dalcin snes->cnvP = cctx; 28263a40ed3dSBarry Smith PetscFunctionReturn(0); 28279b94acceSBarry Smith } 28289b94acceSBarry Smith 28294a2ae208SSatish Balay #undef __FUNCT__ 28304a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 283152baeb72SSatish Balay /*@ 2832184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 2833184914b5SBarry Smith 2834184914b5SBarry Smith Not Collective 2835184914b5SBarry Smith 2836184914b5SBarry Smith Input Parameter: 2837184914b5SBarry Smith . snes - the SNES context 2838184914b5SBarry Smith 2839184914b5SBarry Smith Output Parameter: 28404d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 2841184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 2842184914b5SBarry Smith 2843184914b5SBarry Smith Level: intermediate 2844184914b5SBarry Smith 2845184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 2846184914b5SBarry Smith 2847184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 2848184914b5SBarry Smith 284985385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 2850184914b5SBarry Smith @*/ 28517087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 2852184914b5SBarry Smith { 2853184914b5SBarry Smith PetscFunctionBegin; 28540700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 28554482741eSBarry Smith PetscValidPointer(reason,2); 2856184914b5SBarry Smith *reason = snes->reason; 2857184914b5SBarry Smith PetscFunctionReturn(0); 2858184914b5SBarry Smith } 2859184914b5SBarry Smith 28604a2ae208SSatish Balay #undef __FUNCT__ 28614a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 2862c9005455SLois Curfman McInnes /*@ 2863c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 2864c9005455SLois Curfman McInnes 28653f9fe445SBarry Smith Logically Collective on SNES 2866fee21e36SBarry Smith 2867c7afd0dbSLois Curfman McInnes Input Parameters: 2868c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 28698c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 2870cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 2871758f92a0SBarry Smith . na - size of a and its 287264731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 2873758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 2874c7afd0dbSLois Curfman McInnes 2875308dcc3eSBarry Smith Notes: 2876308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 2877308dcc3eSBarry Smith default array of length 10000 is allocated. 2878308dcc3eSBarry Smith 2879c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 2880c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 2881c9005455SLois Curfman McInnes during the section of code that is being timed. 2882c9005455SLois Curfman McInnes 288336851e7fSLois Curfman McInnes Level: intermediate 288436851e7fSLois Curfman McInnes 2885c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 2886758f92a0SBarry Smith 288708405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 2888758f92a0SBarry Smith 2889c9005455SLois Curfman McInnes @*/ 28907087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 2891c9005455SLois Curfman McInnes { 2892308dcc3eSBarry Smith PetscErrorCode ierr; 2893308dcc3eSBarry Smith 28943a40ed3dSBarry Smith PetscFunctionBegin; 28950700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 28964482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 2897a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 2898308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 2899308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 2900308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 2901308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 2902308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 2903308dcc3eSBarry Smith } 2904c9005455SLois Curfman McInnes snes->conv_hist = a; 2905758f92a0SBarry Smith snes->conv_hist_its = its; 2906758f92a0SBarry Smith snes->conv_hist_max = na; 2907a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 2908758f92a0SBarry Smith snes->conv_hist_reset = reset; 2909758f92a0SBarry Smith PetscFunctionReturn(0); 2910758f92a0SBarry Smith } 2911758f92a0SBarry Smith 2912308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 2913c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 2914c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 2915308dcc3eSBarry Smith EXTERN_C_BEGIN 2916308dcc3eSBarry Smith #undef __FUNCT__ 2917308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 2918308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 2919308dcc3eSBarry Smith { 2920308dcc3eSBarry Smith mxArray *mat; 2921308dcc3eSBarry Smith PetscInt i; 2922308dcc3eSBarry Smith PetscReal *ar; 2923308dcc3eSBarry Smith 2924308dcc3eSBarry Smith PetscFunctionBegin; 2925308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 2926308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 2927308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 2928308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 2929308dcc3eSBarry Smith } 2930308dcc3eSBarry Smith PetscFunctionReturn(mat); 2931308dcc3eSBarry Smith } 2932308dcc3eSBarry Smith EXTERN_C_END 2933308dcc3eSBarry Smith #endif 2934308dcc3eSBarry Smith 2935308dcc3eSBarry Smith 29364a2ae208SSatish Balay #undef __FUNCT__ 29374a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 29380c4c9dddSBarry Smith /*@C 2939758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 2940758f92a0SBarry Smith 29413f9fe445SBarry Smith Not Collective 2942758f92a0SBarry Smith 2943758f92a0SBarry Smith Input Parameter: 2944758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 2945758f92a0SBarry Smith 2946758f92a0SBarry Smith Output Parameters: 2947758f92a0SBarry Smith . a - array to hold history 2948758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 2949758f92a0SBarry Smith negative if not converged) for each solve. 2950758f92a0SBarry Smith - na - size of a and its 2951758f92a0SBarry Smith 2952758f92a0SBarry Smith Notes: 2953758f92a0SBarry Smith The calling sequence for this routine in Fortran is 2954758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 2955758f92a0SBarry Smith 2956758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 2957758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 2958758f92a0SBarry Smith during the section of code that is being timed. 2959758f92a0SBarry Smith 2960758f92a0SBarry Smith Level: intermediate 2961758f92a0SBarry Smith 2962758f92a0SBarry Smith .keywords: SNES, get, convergence, history 2963758f92a0SBarry Smith 2964758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 2965758f92a0SBarry Smith 2966758f92a0SBarry Smith @*/ 29677087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 2968758f92a0SBarry Smith { 2969758f92a0SBarry Smith PetscFunctionBegin; 29700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2971758f92a0SBarry Smith if (a) *a = snes->conv_hist; 2972758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 2973758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 29743a40ed3dSBarry Smith PetscFunctionReturn(0); 2975c9005455SLois Curfman McInnes } 2976c9005455SLois Curfman McInnes 2977e74ef692SMatthew Knepley #undef __FUNCT__ 2978e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 2979ac226902SBarry Smith /*@C 298076b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 2981eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 29827e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 298376b2cf59SMatthew Knepley 29843f9fe445SBarry Smith Logically Collective on SNES 298576b2cf59SMatthew Knepley 298676b2cf59SMatthew Knepley Input Parameters: 298776b2cf59SMatthew Knepley . snes - The nonlinear solver context 298876b2cf59SMatthew Knepley . func - The function 298976b2cf59SMatthew Knepley 299076b2cf59SMatthew Knepley Calling sequence of func: 2991b5d30489SBarry Smith . func (SNES snes, PetscInt step); 299276b2cf59SMatthew Knepley 299376b2cf59SMatthew Knepley . step - The current step of the iteration 299476b2cf59SMatthew Knepley 2995fe97e370SBarry Smith Level: advanced 2996fe97e370SBarry Smith 2997fe97e370SBarry 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() 2998fe97e370SBarry Smith This is not used by most users. 299976b2cf59SMatthew Knepley 300076b2cf59SMatthew Knepley .keywords: SNES, update 3001b5d30489SBarry Smith 300285385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 300376b2cf59SMatthew Knepley @*/ 30047087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 300576b2cf59SMatthew Knepley { 300676b2cf59SMatthew Knepley PetscFunctionBegin; 30070700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3008e7788613SBarry Smith snes->ops->update = func; 300976b2cf59SMatthew Knepley PetscFunctionReturn(0); 301076b2cf59SMatthew Knepley } 301176b2cf59SMatthew Knepley 3012e74ef692SMatthew Knepley #undef __FUNCT__ 3013e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 301476b2cf59SMatthew Knepley /*@ 301576b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 301676b2cf59SMatthew Knepley 301776b2cf59SMatthew Knepley Not collective 301876b2cf59SMatthew Knepley 301976b2cf59SMatthew Knepley Input Parameters: 302076b2cf59SMatthew Knepley . snes - The nonlinear solver context 302176b2cf59SMatthew Knepley . step - The current step of the iteration 302276b2cf59SMatthew Knepley 3023205452f4SMatthew Knepley Level: intermediate 3024205452f4SMatthew Knepley 302576b2cf59SMatthew Knepley .keywords: SNES, update 3026a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 302776b2cf59SMatthew Knepley @*/ 30287087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 302976b2cf59SMatthew Knepley { 303076b2cf59SMatthew Knepley PetscFunctionBegin; 303176b2cf59SMatthew Knepley PetscFunctionReturn(0); 303276b2cf59SMatthew Knepley } 303376b2cf59SMatthew Knepley 30344a2ae208SSatish Balay #undef __FUNCT__ 30354a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 30369b94acceSBarry Smith /* 30379b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 30389b94acceSBarry Smith positive parameter delta. 30399b94acceSBarry Smith 30409b94acceSBarry Smith Input Parameters: 3041c7afd0dbSLois Curfman McInnes + snes - the SNES context 30429b94acceSBarry Smith . y - approximate solution of linear system 30439b94acceSBarry Smith . fnorm - 2-norm of current function 3044c7afd0dbSLois Curfman McInnes - delta - trust region size 30459b94acceSBarry Smith 30469b94acceSBarry Smith Output Parameters: 3047c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 30489b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 30499b94acceSBarry Smith region, and exceeds zero otherwise. 3050c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 30519b94acceSBarry Smith 30529b94acceSBarry Smith Note: 30534b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 30549b94acceSBarry Smith is set to be the maximum allowable step size. 30559b94acceSBarry Smith 30569b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 30579b94acceSBarry Smith */ 3058dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 30599b94acceSBarry Smith { 3060064f8208SBarry Smith PetscReal nrm; 3061ea709b57SSatish Balay PetscScalar cnorm; 3062dfbe8321SBarry Smith PetscErrorCode ierr; 30633a40ed3dSBarry Smith 30643a40ed3dSBarry Smith PetscFunctionBegin; 30650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 30660700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3067c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3068184914b5SBarry Smith 3069064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3070064f8208SBarry Smith if (nrm > *delta) { 3071064f8208SBarry Smith nrm = *delta/nrm; 3072064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3073064f8208SBarry Smith cnorm = nrm; 30742dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 30759b94acceSBarry Smith *ynorm = *delta; 30769b94acceSBarry Smith } else { 30779b94acceSBarry Smith *gpnorm = 0.0; 3078064f8208SBarry Smith *ynorm = nrm; 30799b94acceSBarry Smith } 30803a40ed3dSBarry Smith PetscFunctionReturn(0); 30819b94acceSBarry Smith } 30829b94acceSBarry Smith 30834a2ae208SSatish Balay #undef __FUNCT__ 30844a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 30856ce558aeSBarry Smith /*@C 3086f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3087f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 30889b94acceSBarry Smith 3089c7afd0dbSLois Curfman McInnes Collective on SNES 3090c7afd0dbSLois Curfman McInnes 3091b2002411SLois Curfman McInnes Input Parameters: 3092c7afd0dbSLois Curfman McInnes + snes - the SNES context 30933cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 309485385478SLisandro Dalcin - x - the solution vector. 30959b94acceSBarry Smith 3096b2002411SLois Curfman McInnes Notes: 30978ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 30988ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 30998ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 31008ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 31018ddd3da0SLois Curfman McInnes 310236851e7fSLois Curfman McInnes Level: beginner 310336851e7fSLois Curfman McInnes 31049b94acceSBarry Smith .keywords: SNES, nonlinear, solve 31059b94acceSBarry Smith 3106c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 31079b94acceSBarry Smith @*/ 31087087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 31099b94acceSBarry Smith { 3110dfbe8321SBarry Smith PetscErrorCode ierr; 3111ace3abfcSBarry Smith PetscBool flg; 3112eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 3113eabae89aSBarry Smith PetscViewer viewer; 3114efd51863SBarry Smith PetscInt grid; 3115a69afd8bSBarry Smith Vec xcreated = PETSC_NULL; 3116052efed2SBarry Smith 31173a40ed3dSBarry Smith PetscFunctionBegin; 31180700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3119a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3120a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 31210700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 312285385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 312385385478SLisandro Dalcin 3124a69afd8bSBarry Smith if (!x && snes->dm) { 3125a69afd8bSBarry Smith ierr = DMCreateGlobalVector(snes->dm,&xcreated);CHKERRQ(ierr); 3126a69afd8bSBarry Smith x = xcreated; 3127a69afd8bSBarry Smith } 3128a69afd8bSBarry Smith 3129a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3130efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3131efd51863SBarry Smith 313285385478SLisandro Dalcin /* set solution vector */ 3133efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 31346bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 313585385478SLisandro Dalcin snes->vec_sol = x; 313685385478SLisandro Dalcin /* set afine vector if provided */ 313785385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 31386bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 313985385478SLisandro Dalcin snes->vec_rhs = b; 314085385478SLisandro Dalcin 314170e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 31423f149594SLisandro Dalcin 31437eee914bSBarry Smith if (!grid) { 31447eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3145d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3146dd568438SSatish Balay } else if (snes->dm) { 3147dd568438SSatish Balay PetscBool ig; 3148dd568438SSatish Balay ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr); 3149dd568438SSatish Balay if (ig) { 31507eee914bSBarry Smith ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr); 31517eee914bSBarry Smith } 3152d25893d9SBarry Smith } 3153dd568438SSatish Balay } 3154d25893d9SBarry Smith 3155abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 315650ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3157d5e45103SBarry Smith 31583f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 31594936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 316085385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 31614936397dSBarry Smith if (snes->domainerror){ 31624936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 31634936397dSBarry Smith snes->domainerror = PETSC_FALSE; 31644936397dSBarry Smith } 316517186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 31663f149594SLisandro Dalcin 31677adad957SLisandro Dalcin ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 3168eabae89aSBarry Smith if (flg && !PetscPreLoadingOn) { 31697adad957SLisandro Dalcin ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 3170eabae89aSBarry Smith ierr = SNESView(snes,viewer);CHKERRQ(ierr); 31716bf464f9SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3172eabae89aSBarry Smith } 3173eabae89aSBarry Smith 317490d69ab7SBarry Smith flg = PETSC_FALSE; 3175acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3176da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 31775968eb51SBarry Smith if (snes->printreason) { 3178a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 31795968eb51SBarry Smith if (snes->reason > 0) { 3180a8248277SBarry Smith ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 31815968eb51SBarry Smith } else { 3182a8248277SBarry Smith ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 31835968eb51SBarry Smith } 3184a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 31855968eb51SBarry Smith } 31865968eb51SBarry Smith 31878501fc72SJed Brown flg = PETSC_FALSE; 31888501fc72SJed Brown ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 31898501fc72SJed Brown if (flg) { 31908501fc72SJed Brown PetscViewer viewer; 31918501fc72SJed Brown ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 31928501fc72SJed Brown ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 31938501fc72SJed Brown ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 31948501fc72SJed Brown ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 31958501fc72SJed Brown ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 31968501fc72SJed Brown } 31978501fc72SJed Brown 3198e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3199efd51863SBarry Smith if (grid < snes->gridsequence) { 3200efd51863SBarry Smith DM fine; 3201efd51863SBarry Smith Vec xnew; 3202efd51863SBarry Smith Mat interp; 3203efd51863SBarry Smith 3204efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3205e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3206efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3207efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3208efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3209efd51863SBarry Smith x = xnew; 3210efd51863SBarry Smith 3211efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3212efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3213efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3214a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3215efd51863SBarry Smith } 3216efd51863SBarry Smith } 3217a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 32183a40ed3dSBarry Smith PetscFunctionReturn(0); 32199b94acceSBarry Smith } 32209b94acceSBarry Smith 32219b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 32229b94acceSBarry Smith 32234a2ae208SSatish Balay #undef __FUNCT__ 32244a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 322582bf6240SBarry Smith /*@C 32264b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 32279b94acceSBarry Smith 3228fee21e36SBarry Smith Collective on SNES 3229fee21e36SBarry Smith 3230c7afd0dbSLois Curfman McInnes Input Parameters: 3231c7afd0dbSLois Curfman McInnes + snes - the SNES context 3232454a90a3SBarry Smith - type - a known method 3233c7afd0dbSLois Curfman McInnes 3234c7afd0dbSLois Curfman McInnes Options Database Key: 3235454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3236c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3237ae12b187SLois Curfman McInnes 32389b94acceSBarry Smith Notes: 3239e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 32404b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3241c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 32424b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3243c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 32449b94acceSBarry Smith 3245ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3246ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3247ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3248ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3249ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3250ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3251ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3252ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3253ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3254b0a32e0cSBarry Smith appropriate method. 325536851e7fSLois Curfman McInnes 325636851e7fSLois Curfman McInnes Level: intermediate 3257a703fe33SLois Curfman McInnes 3258454a90a3SBarry Smith .keywords: SNES, set, type 3259435da068SBarry Smith 3260435da068SBarry Smith .seealso: SNESType, SNESCreate() 3261435da068SBarry Smith 32629b94acceSBarry Smith @*/ 32637087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 32649b94acceSBarry Smith { 3265dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3266ace3abfcSBarry Smith PetscBool match; 32673a40ed3dSBarry Smith 32683a40ed3dSBarry Smith PetscFunctionBegin; 32690700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 32704482741eSBarry Smith PetscValidCharPointer(type,2); 327182bf6240SBarry Smith 32726831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 32730f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 327492ff6ae8SBarry Smith 32754b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3276e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 327775396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 327875396ef9SLisandro Dalcin if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); } 327975396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 328075396ef9SLisandro Dalcin snes->ops->setup = 0; 328175396ef9SLisandro Dalcin snes->ops->solve = 0; 328275396ef9SLisandro Dalcin snes->ops->view = 0; 328375396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 328475396ef9SLisandro Dalcin snes->ops->destroy = 0; 328575396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 328675396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3287454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 328803bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 32899fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 32909fb22e1aSBarry Smith if (PetscAMSPublishAll) { 32919fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 32929fb22e1aSBarry Smith } 32939fb22e1aSBarry Smith #endif 32943a40ed3dSBarry Smith PetscFunctionReturn(0); 32959b94acceSBarry Smith } 32969b94acceSBarry Smith 3297a847f771SSatish Balay 32989b94acceSBarry Smith /* --------------------------------------------------------------------- */ 32994a2ae208SSatish Balay #undef __FUNCT__ 33004a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 330152baeb72SSatish Balay /*@ 33029b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3303f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 33049b94acceSBarry Smith 3305fee21e36SBarry Smith Not Collective 3306fee21e36SBarry Smith 330736851e7fSLois Curfman McInnes Level: advanced 330836851e7fSLois Curfman McInnes 33099b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 33109b94acceSBarry Smith 33119b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 33129b94acceSBarry Smith @*/ 33137087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 33149b94acceSBarry Smith { 3315dfbe8321SBarry Smith PetscErrorCode ierr; 331682bf6240SBarry Smith 33173a40ed3dSBarry Smith PetscFunctionBegin; 33181441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 33194c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 33203a40ed3dSBarry Smith PetscFunctionReturn(0); 33219b94acceSBarry Smith } 33229b94acceSBarry Smith 33234a2ae208SSatish Balay #undef __FUNCT__ 33244a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 33259b94acceSBarry Smith /*@C 33269a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 33279b94acceSBarry Smith 3328c7afd0dbSLois Curfman McInnes Not Collective 3329c7afd0dbSLois Curfman McInnes 33309b94acceSBarry Smith Input Parameter: 33314b0e389bSBarry Smith . snes - nonlinear solver context 33329b94acceSBarry Smith 33339b94acceSBarry Smith Output Parameter: 33343a7fca6bSBarry Smith . type - SNES method (a character string) 33359b94acceSBarry Smith 333636851e7fSLois Curfman McInnes Level: intermediate 333736851e7fSLois Curfman McInnes 3338454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 33399b94acceSBarry Smith @*/ 33407087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 33419b94acceSBarry Smith { 33423a40ed3dSBarry Smith PetscFunctionBegin; 33430700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 33444482741eSBarry Smith PetscValidPointer(type,2); 33457adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 33463a40ed3dSBarry Smith PetscFunctionReturn(0); 33479b94acceSBarry Smith } 33489b94acceSBarry Smith 33494a2ae208SSatish Balay #undef __FUNCT__ 33504a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 335152baeb72SSatish Balay /*@ 33529b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3353c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 33549b94acceSBarry Smith 3355c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3356c7afd0dbSLois Curfman McInnes 33579b94acceSBarry Smith Input Parameter: 33589b94acceSBarry Smith . snes - the SNES context 33599b94acceSBarry Smith 33609b94acceSBarry Smith Output Parameter: 33619b94acceSBarry Smith . x - the solution 33629b94acceSBarry Smith 336370e92668SMatthew Knepley Level: intermediate 336436851e7fSLois Curfman McInnes 33659b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 33669b94acceSBarry Smith 336785385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 33689b94acceSBarry Smith @*/ 33697087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 33709b94acceSBarry Smith { 33713a40ed3dSBarry Smith PetscFunctionBegin; 33720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 33734482741eSBarry Smith PetscValidPointer(x,2); 337485385478SLisandro Dalcin *x = snes->vec_sol; 337570e92668SMatthew Knepley PetscFunctionReturn(0); 337670e92668SMatthew Knepley } 337770e92668SMatthew Knepley 337870e92668SMatthew Knepley #undef __FUNCT__ 33794a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 338052baeb72SSatish Balay /*@ 33819b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 33829b94acceSBarry Smith stored. 33839b94acceSBarry Smith 3384c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3385c7afd0dbSLois Curfman McInnes 33869b94acceSBarry Smith Input Parameter: 33879b94acceSBarry Smith . snes - the SNES context 33889b94acceSBarry Smith 33899b94acceSBarry Smith Output Parameter: 33909b94acceSBarry Smith . x - the solution update 33919b94acceSBarry Smith 339236851e7fSLois Curfman McInnes Level: advanced 339336851e7fSLois Curfman McInnes 33949b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 33959b94acceSBarry Smith 339685385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 33979b94acceSBarry Smith @*/ 33987087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 33999b94acceSBarry Smith { 34003a40ed3dSBarry Smith PetscFunctionBegin; 34010700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34024482741eSBarry Smith PetscValidPointer(x,2); 340385385478SLisandro Dalcin *x = snes->vec_sol_update; 34043a40ed3dSBarry Smith PetscFunctionReturn(0); 34059b94acceSBarry Smith } 34069b94acceSBarry Smith 34074a2ae208SSatish Balay #undef __FUNCT__ 34084a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 34099b94acceSBarry Smith /*@C 34103638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 34119b94acceSBarry Smith 3412a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 3413c7afd0dbSLois Curfman McInnes 34149b94acceSBarry Smith Input Parameter: 34159b94acceSBarry Smith . snes - the SNES context 34169b94acceSBarry Smith 34179b94acceSBarry Smith Output Parameter: 34187bf4e008SBarry Smith + r - the function (or PETSC_NULL) 341970e92668SMatthew Knepley . func - the function (or PETSC_NULL) 342070e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 34219b94acceSBarry Smith 342236851e7fSLois Curfman McInnes Level: advanced 342336851e7fSLois Curfman McInnes 3424a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 34259b94acceSBarry Smith 34264b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 34279b94acceSBarry Smith @*/ 34287087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 34299b94acceSBarry Smith { 3430a63bb30eSJed Brown PetscErrorCode ierr; 3431a63bb30eSJed Brown 34323a40ed3dSBarry Smith PetscFunctionBegin; 34330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3434a63bb30eSJed Brown if (r) { 3435a63bb30eSJed Brown if (!snes->vec_func) { 3436a63bb30eSJed Brown if (snes->vec_rhs) { 3437a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 3438a63bb30eSJed Brown } else if (snes->vec_sol) { 3439a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 3440a63bb30eSJed Brown } else if (snes->dm) { 3441a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 3442a63bb30eSJed Brown } 3443a63bb30eSJed Brown } 3444a63bb30eSJed Brown *r = snes->vec_func; 3445a63bb30eSJed Brown } 3446e7788613SBarry Smith if (func) *func = snes->ops->computefunction; 344770e92668SMatthew Knepley if (ctx) *ctx = snes->funP; 34483a40ed3dSBarry Smith PetscFunctionReturn(0); 34499b94acceSBarry Smith } 34509b94acceSBarry Smith 3451c79ef259SPeter Brune /*@C 3452c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3453c79ef259SPeter Brune 3454c79ef259SPeter Brune Input Parameter: 3455c79ef259SPeter Brune . snes - the SNES context 3456c79ef259SPeter Brune 3457c79ef259SPeter Brune Output Parameter: 3458c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3459c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3460c79ef259SPeter Brune 3461c79ef259SPeter Brune Level: advanced 3462c79ef259SPeter Brune 3463c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3464c79ef259SPeter Brune 3465c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3466c79ef259SPeter Brune @*/ 3467c79ef259SPeter Brune 34684a2ae208SSatish Balay #undef __FUNCT__ 3469646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3470646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3471646217ecSPeter Brune { 3472646217ecSPeter Brune PetscFunctionBegin; 3473646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3474646217ecSPeter Brune if (func) *func = snes->ops->computegs; 3475646217ecSPeter Brune if (ctx) *ctx = snes->funP; 3476646217ecSPeter Brune PetscFunctionReturn(0); 3477646217ecSPeter Brune } 3478646217ecSPeter Brune 34794a2ae208SSatish Balay #undef __FUNCT__ 34804a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 34813c7409f5SSatish Balay /*@C 34823c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3483d850072dSLois Curfman McInnes SNES options in the database. 34843c7409f5SSatish Balay 34853f9fe445SBarry Smith Logically Collective on SNES 3486fee21e36SBarry Smith 3487c7afd0dbSLois Curfman McInnes Input Parameter: 3488c7afd0dbSLois Curfman McInnes + snes - the SNES context 3489c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3490c7afd0dbSLois Curfman McInnes 3491d850072dSLois Curfman McInnes Notes: 3492a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3493c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3494d850072dSLois Curfman McInnes 349536851e7fSLois Curfman McInnes Level: advanced 349636851e7fSLois Curfman McInnes 34973c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3498a86d99e1SLois Curfman McInnes 3499a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 35003c7409f5SSatish Balay @*/ 35017087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 35023c7409f5SSatish Balay { 3503dfbe8321SBarry Smith PetscErrorCode ierr; 35043c7409f5SSatish Balay 35053a40ed3dSBarry Smith PetscFunctionBegin; 35060700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3507639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 35081cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 350994b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 35103a40ed3dSBarry Smith PetscFunctionReturn(0); 35113c7409f5SSatish Balay } 35123c7409f5SSatish Balay 35134a2ae208SSatish Balay #undef __FUNCT__ 35144a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 35153c7409f5SSatish Balay /*@C 3516f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3517d850072dSLois Curfman McInnes SNES options in the database. 35183c7409f5SSatish Balay 35193f9fe445SBarry Smith Logically Collective on SNES 3520fee21e36SBarry Smith 3521c7afd0dbSLois Curfman McInnes Input Parameters: 3522c7afd0dbSLois Curfman McInnes + snes - the SNES context 3523c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3524c7afd0dbSLois Curfman McInnes 3525d850072dSLois Curfman McInnes Notes: 3526a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3527c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3528d850072dSLois Curfman McInnes 352936851e7fSLois Curfman McInnes Level: advanced 353036851e7fSLois Curfman McInnes 35313c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3532a86d99e1SLois Curfman McInnes 3533a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 35343c7409f5SSatish Balay @*/ 35357087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 35363c7409f5SSatish Balay { 3537dfbe8321SBarry Smith PetscErrorCode ierr; 35383c7409f5SSatish Balay 35393a40ed3dSBarry Smith PetscFunctionBegin; 35400700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3541639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 35421cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 354394b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 35443a40ed3dSBarry Smith PetscFunctionReturn(0); 35453c7409f5SSatish Balay } 35463c7409f5SSatish Balay 35474a2ae208SSatish Balay #undef __FUNCT__ 35484a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 35499ab63eb5SSatish Balay /*@C 35503c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 35513c7409f5SSatish Balay SNES options in the database. 35523c7409f5SSatish Balay 3553c7afd0dbSLois Curfman McInnes Not Collective 3554c7afd0dbSLois Curfman McInnes 35553c7409f5SSatish Balay Input Parameter: 35563c7409f5SSatish Balay . snes - the SNES context 35573c7409f5SSatish Balay 35583c7409f5SSatish Balay Output Parameter: 35593c7409f5SSatish Balay . prefix - pointer to the prefix string used 35603c7409f5SSatish Balay 35614ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 35629ab63eb5SSatish Balay sufficient length to hold the prefix. 35639ab63eb5SSatish Balay 356436851e7fSLois Curfman McInnes Level: advanced 356536851e7fSLois Curfman McInnes 35663c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 3567a86d99e1SLois Curfman McInnes 3568a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 35693c7409f5SSatish Balay @*/ 35707087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 35713c7409f5SSatish Balay { 3572dfbe8321SBarry Smith PetscErrorCode ierr; 35733c7409f5SSatish Balay 35743a40ed3dSBarry Smith PetscFunctionBegin; 35750700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3576639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 35773a40ed3dSBarry Smith PetscFunctionReturn(0); 35783c7409f5SSatish Balay } 35793c7409f5SSatish Balay 3580b2002411SLois Curfman McInnes 35814a2ae208SSatish Balay #undef __FUNCT__ 35824a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 35833cea93caSBarry Smith /*@C 35843cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 35853cea93caSBarry Smith 35867f6c08e0SMatthew Knepley Level: advanced 35873cea93caSBarry Smith @*/ 35887087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3589b2002411SLois Curfman McInnes { 3590e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3591dfbe8321SBarry Smith PetscErrorCode ierr; 3592b2002411SLois Curfman McInnes 3593b2002411SLois Curfman McInnes PetscFunctionBegin; 3594b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3595c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3596b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3597b2002411SLois Curfman McInnes } 3598da9b6338SBarry Smith 3599da9b6338SBarry Smith #undef __FUNCT__ 3600da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 36017087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3602da9b6338SBarry Smith { 3603dfbe8321SBarry Smith PetscErrorCode ierr; 360477431f27SBarry Smith PetscInt N,i,j; 3605da9b6338SBarry Smith Vec u,uh,fh; 3606da9b6338SBarry Smith PetscScalar value; 3607da9b6338SBarry Smith PetscReal norm; 3608da9b6338SBarry Smith 3609da9b6338SBarry Smith PetscFunctionBegin; 3610da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3611da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3612da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3613da9b6338SBarry Smith 3614da9b6338SBarry Smith /* currently only works for sequential */ 3615da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3616da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3617da9b6338SBarry Smith for (i=0; i<N; i++) { 3618da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 361977431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3620da9b6338SBarry Smith for (j=-10; j<11; j++) { 3621ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3622da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 36233ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3624da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 362577431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3626da9b6338SBarry Smith value = -value; 3627da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3628da9b6338SBarry Smith } 3629da9b6338SBarry Smith } 36306bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 36316bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 3632da9b6338SBarry Smith PetscFunctionReturn(0); 3633da9b6338SBarry Smith } 363471f87433Sdalcinl 363571f87433Sdalcinl #undef __FUNCT__ 3636fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 363771f87433Sdalcinl /*@ 3638fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 363971f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 364071f87433Sdalcinl Newton method. 364171f87433Sdalcinl 36423f9fe445SBarry Smith Logically Collective on SNES 364371f87433Sdalcinl 364471f87433Sdalcinl Input Parameters: 364571f87433Sdalcinl + snes - SNES context 364671f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 364771f87433Sdalcinl 364864ba62caSBarry Smith Options Database: 364964ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 365064ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 365164ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 365264ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 365364ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 365464ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 365564ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 365664ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 365764ba62caSBarry Smith 365871f87433Sdalcinl Notes: 365971f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 366071f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 366171f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 366271f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 366371f87433Sdalcinl solver. 366471f87433Sdalcinl 366571f87433Sdalcinl Level: advanced 366671f87433Sdalcinl 366771f87433Sdalcinl Reference: 366871f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 366971f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 367071f87433Sdalcinl 367171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 367271f87433Sdalcinl 3673fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 367471f87433Sdalcinl @*/ 36757087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 367671f87433Sdalcinl { 367771f87433Sdalcinl PetscFunctionBegin; 36780700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3679acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 368071f87433Sdalcinl snes->ksp_ewconv = flag; 368171f87433Sdalcinl PetscFunctionReturn(0); 368271f87433Sdalcinl } 368371f87433Sdalcinl 368471f87433Sdalcinl #undef __FUNCT__ 3685fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 368671f87433Sdalcinl /*@ 3687fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 368871f87433Sdalcinl for computing relative tolerance for linear solvers within an 368971f87433Sdalcinl inexact Newton method. 369071f87433Sdalcinl 369171f87433Sdalcinl Not Collective 369271f87433Sdalcinl 369371f87433Sdalcinl Input Parameter: 369471f87433Sdalcinl . snes - SNES context 369571f87433Sdalcinl 369671f87433Sdalcinl Output Parameter: 369771f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 369871f87433Sdalcinl 369971f87433Sdalcinl Notes: 370071f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 370171f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 370271f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 370371f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 370471f87433Sdalcinl solver. 370571f87433Sdalcinl 370671f87433Sdalcinl Level: advanced 370771f87433Sdalcinl 370871f87433Sdalcinl Reference: 370971f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 371071f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 371171f87433Sdalcinl 371271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 371371f87433Sdalcinl 3714fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 371571f87433Sdalcinl @*/ 37167087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 371771f87433Sdalcinl { 371871f87433Sdalcinl PetscFunctionBegin; 37190700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 372071f87433Sdalcinl PetscValidPointer(flag,2); 372171f87433Sdalcinl *flag = snes->ksp_ewconv; 372271f87433Sdalcinl PetscFunctionReturn(0); 372371f87433Sdalcinl } 372471f87433Sdalcinl 372571f87433Sdalcinl #undef __FUNCT__ 3726fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 372771f87433Sdalcinl /*@ 3728fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 372971f87433Sdalcinl convergence criteria for the linear solvers within an inexact 373071f87433Sdalcinl Newton method. 373171f87433Sdalcinl 37323f9fe445SBarry Smith Logically Collective on SNES 373371f87433Sdalcinl 373471f87433Sdalcinl Input Parameters: 373571f87433Sdalcinl + snes - SNES context 373671f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 373771f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 373871f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 373971f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 374071f87433Sdalcinl (0 <= gamma2 <= 1) 374171f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 374271f87433Sdalcinl . alpha2 - power for safeguard 374371f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 374471f87433Sdalcinl 374571f87433Sdalcinl Note: 374671f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 374771f87433Sdalcinl 374871f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 374971f87433Sdalcinl 375071f87433Sdalcinl Level: advanced 375171f87433Sdalcinl 375271f87433Sdalcinl Reference: 375371f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 375471f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 375571f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 375671f87433Sdalcinl 375771f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 375871f87433Sdalcinl 3759fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 376071f87433Sdalcinl @*/ 37617087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 376271f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 376371f87433Sdalcinl { 3764fa9f3622SBarry Smith SNESKSPEW *kctx; 376571f87433Sdalcinl PetscFunctionBegin; 37660700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3767fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3768e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 3769c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 3770c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 3771c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 3772c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 3773c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 3774c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 3775c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 377671f87433Sdalcinl 377771f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 377871f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 377971f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 378071f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 378171f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 378271f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 378371f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 378471f87433Sdalcinl 378571f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 3786e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 378771f87433Sdalcinl } 378871f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 3789e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 379071f87433Sdalcinl } 379171f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 3792e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 379371f87433Sdalcinl } 379471f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 3795e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 379671f87433Sdalcinl } 379771f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 3798e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 379971f87433Sdalcinl } 380071f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 3801e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 380271f87433Sdalcinl } 380371f87433Sdalcinl PetscFunctionReturn(0); 380471f87433Sdalcinl } 380571f87433Sdalcinl 380671f87433Sdalcinl #undef __FUNCT__ 3807fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 380871f87433Sdalcinl /*@ 3809fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 381071f87433Sdalcinl convergence criteria for the linear solvers within an inexact 381171f87433Sdalcinl Newton method. 381271f87433Sdalcinl 381371f87433Sdalcinl Not Collective 381471f87433Sdalcinl 381571f87433Sdalcinl Input Parameters: 381671f87433Sdalcinl snes - SNES context 381771f87433Sdalcinl 381871f87433Sdalcinl Output Parameters: 381971f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 382071f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 382171f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 382271f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 382371f87433Sdalcinl (0 <= gamma2 <= 1) 382471f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 382571f87433Sdalcinl . alpha2 - power for safeguard 382671f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 382771f87433Sdalcinl 382871f87433Sdalcinl Level: advanced 382971f87433Sdalcinl 383071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 383171f87433Sdalcinl 3832fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 383371f87433Sdalcinl @*/ 38347087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 383571f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 383671f87433Sdalcinl { 3837fa9f3622SBarry Smith SNESKSPEW *kctx; 383871f87433Sdalcinl PetscFunctionBegin; 38390700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3840fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3841e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 384271f87433Sdalcinl if(version) *version = kctx->version; 384371f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 384471f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 384571f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 384671f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 384771f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 384871f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 384971f87433Sdalcinl PetscFunctionReturn(0); 385071f87433Sdalcinl } 385171f87433Sdalcinl 385271f87433Sdalcinl #undef __FUNCT__ 3853fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 3854fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 385571f87433Sdalcinl { 385671f87433Sdalcinl PetscErrorCode ierr; 3857fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 385871f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 385971f87433Sdalcinl 386071f87433Sdalcinl PetscFunctionBegin; 3861e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 386271f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 386371f87433Sdalcinl rtol = kctx->rtol_0; 386471f87433Sdalcinl } else { 386571f87433Sdalcinl if (kctx->version == 1) { 386671f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 386771f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 386871f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 386971f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 387071f87433Sdalcinl } else if (kctx->version == 2) { 387171f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 387271f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 387371f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 387471f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 387571f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 387671f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 387771f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 387871f87433Sdalcinl stol = PetscMax(rtol,stol); 387971f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 388071f87433Sdalcinl /* safeguard: avoid oversolving */ 388171f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 388271f87433Sdalcinl stol = PetscMax(rtol,stol); 388371f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 3884e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 388571f87433Sdalcinl } 388671f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 388771f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 388871f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 388971f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 389071f87433Sdalcinl PetscFunctionReturn(0); 389171f87433Sdalcinl } 389271f87433Sdalcinl 389371f87433Sdalcinl #undef __FUNCT__ 3894fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 3895fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 389671f87433Sdalcinl { 389771f87433Sdalcinl PetscErrorCode ierr; 3898fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 389971f87433Sdalcinl PCSide pcside; 390071f87433Sdalcinl Vec lres; 390171f87433Sdalcinl 390271f87433Sdalcinl PetscFunctionBegin; 3903e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 390471f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 390571f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 390671f87433Sdalcinl if (kctx->version == 1) { 3907b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 390871f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 390971f87433Sdalcinl /* KSP residual is true linear residual */ 391071f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 391171f87433Sdalcinl } else { 391271f87433Sdalcinl /* KSP residual is preconditioned residual */ 391371f87433Sdalcinl /* compute true linear residual norm */ 391471f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 391571f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 391671f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 391771f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 39186bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 391971f87433Sdalcinl } 392071f87433Sdalcinl } 392171f87433Sdalcinl PetscFunctionReturn(0); 392271f87433Sdalcinl } 392371f87433Sdalcinl 392471f87433Sdalcinl #undef __FUNCT__ 392571f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 392671f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 392771f87433Sdalcinl { 392871f87433Sdalcinl PetscErrorCode ierr; 392971f87433Sdalcinl 393071f87433Sdalcinl PetscFunctionBegin; 3931fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 393271f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 3933fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 393471f87433Sdalcinl PetscFunctionReturn(0); 393571f87433Sdalcinl } 39366c699258SBarry Smith 39376c699258SBarry Smith #undef __FUNCT__ 39386c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 39396c699258SBarry Smith /*@ 39406c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 39416c699258SBarry Smith 39423f9fe445SBarry Smith Logically Collective on SNES 39436c699258SBarry Smith 39446c699258SBarry Smith Input Parameters: 39456c699258SBarry Smith + snes - the preconditioner context 39466c699258SBarry Smith - dm - the dm 39476c699258SBarry Smith 39486c699258SBarry Smith Level: intermediate 39496c699258SBarry Smith 39506c699258SBarry Smith 39516c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 39526c699258SBarry Smith @*/ 39537087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 39546c699258SBarry Smith { 39556c699258SBarry Smith PetscErrorCode ierr; 3956345fed2cSBarry Smith KSP ksp; 39576c699258SBarry Smith 39586c699258SBarry Smith PetscFunctionBegin; 39590700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3960d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 39616bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 39626c699258SBarry Smith snes->dm = dm; 3963345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 3964345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 3965f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 39662c155ee1SBarry Smith if (snes->pc) { 39672c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 39682c155ee1SBarry Smith } 39696c699258SBarry Smith PetscFunctionReturn(0); 39706c699258SBarry Smith } 39716c699258SBarry Smith 39726c699258SBarry Smith #undef __FUNCT__ 39736c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 39746c699258SBarry Smith /*@ 39756c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 39766c699258SBarry Smith 39773f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 39786c699258SBarry Smith 39796c699258SBarry Smith Input Parameter: 39806c699258SBarry Smith . snes - the preconditioner context 39816c699258SBarry Smith 39826c699258SBarry Smith Output Parameter: 39836c699258SBarry Smith . dm - the dm 39846c699258SBarry Smith 39856c699258SBarry Smith Level: intermediate 39866c699258SBarry Smith 39876c699258SBarry Smith 39886c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 39896c699258SBarry Smith @*/ 39907087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 39916c699258SBarry Smith { 39926c699258SBarry Smith PetscFunctionBegin; 39930700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 39946c699258SBarry Smith *dm = snes->dm; 39956c699258SBarry Smith PetscFunctionReturn(0); 39966c699258SBarry Smith } 39970807856dSBarry Smith 399831823bd8SMatthew G Knepley #undef __FUNCT__ 399931823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 400031823bd8SMatthew G Knepley /*@ 4001fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 400231823bd8SMatthew G Knepley 400331823bd8SMatthew G Knepley Collective on SNES 400431823bd8SMatthew G Knepley 400531823bd8SMatthew G Knepley Input Parameters: 400631823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 400731823bd8SMatthew G Knepley - pc - the preconditioner object 400831823bd8SMatthew G Knepley 400931823bd8SMatthew G Knepley Notes: 401031823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 401131823bd8SMatthew G Knepley to configure it using the API). 401231823bd8SMatthew G Knepley 401331823bd8SMatthew G Knepley Level: developer 401431823bd8SMatthew G Knepley 401531823bd8SMatthew G Knepley .keywords: SNES, set, precondition 401631823bd8SMatthew G Knepley .seealso: SNESGetPC() 401731823bd8SMatthew G Knepley @*/ 401831823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 401931823bd8SMatthew G Knepley { 402031823bd8SMatthew G Knepley PetscErrorCode ierr; 402131823bd8SMatthew G Knepley 402231823bd8SMatthew G Knepley PetscFunctionBegin; 402331823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 402431823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 402531823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 402631823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4027bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 402831823bd8SMatthew G Knepley snes->pc = pc; 402931823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 403031823bd8SMatthew G Knepley PetscFunctionReturn(0); 403131823bd8SMatthew G Knepley } 403231823bd8SMatthew G Knepley 403331823bd8SMatthew G Knepley #undef __FUNCT__ 403431823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 403531823bd8SMatthew G Knepley /*@ 4036fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 403731823bd8SMatthew G Knepley 403831823bd8SMatthew G Knepley Not Collective 403931823bd8SMatthew G Knepley 404031823bd8SMatthew G Knepley Input Parameter: 404131823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 404231823bd8SMatthew G Knepley 404331823bd8SMatthew G Knepley Output Parameter: 404431823bd8SMatthew G Knepley . pc - preconditioner context 404531823bd8SMatthew G Knepley 404631823bd8SMatthew G Knepley Level: developer 404731823bd8SMatthew G Knepley 404831823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 404931823bd8SMatthew G Knepley .seealso: SNESSetPC() 405031823bd8SMatthew G Knepley @*/ 405131823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 405231823bd8SMatthew G Knepley { 405331823bd8SMatthew G Knepley PetscErrorCode ierr; 405431823bd8SMatthew G Knepley 405531823bd8SMatthew G Knepley PetscFunctionBegin; 405631823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 405731823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 405831823bd8SMatthew G Knepley if (!snes->pc) { 405931823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr); 40604a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr); 406131823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 406231823bd8SMatthew G Knepley } 406331823bd8SMatthew G Knepley *pc = snes->pc; 406431823bd8SMatthew G Knepley PetscFunctionReturn(0); 406531823bd8SMatthew G Knepley } 406631823bd8SMatthew G Knepley 406769b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4068c6db04a5SJed Brown #include <mex.h> 406969b4f73cSBarry Smith 40708f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 40718f6e6473SBarry Smith 40720807856dSBarry Smith #undef __FUNCT__ 40730807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 40740807856dSBarry Smith /* 40750807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 40760807856dSBarry Smith SNESSetFunctionMatlab(). 40770807856dSBarry Smith 40780807856dSBarry Smith Collective on SNES 40790807856dSBarry Smith 40800807856dSBarry Smith Input Parameters: 40810807856dSBarry Smith + snes - the SNES context 40820807856dSBarry Smith - x - input vector 40830807856dSBarry Smith 40840807856dSBarry Smith Output Parameter: 40850807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 40860807856dSBarry Smith 40870807856dSBarry Smith Notes: 40880807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 40890807856dSBarry Smith implementations, so most users would not generally call this routine 40900807856dSBarry Smith themselves. 40910807856dSBarry Smith 40920807856dSBarry Smith Level: developer 40930807856dSBarry Smith 40940807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 40950807856dSBarry Smith 40960807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 409761b2408cSBarry Smith */ 40987087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 40990807856dSBarry Smith { 4100e650e774SBarry Smith PetscErrorCode ierr; 41018f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 41028f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 41038f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 410491621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 4105e650e774SBarry Smith 41060807856dSBarry Smith PetscFunctionBegin; 41070807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 41080807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 41090807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 41100807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 41110807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 41120807856dSBarry Smith 41130807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 4114e650e774SBarry Smith 411591621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4116e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4117e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 411891621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 411991621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 412091621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 41218f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 41228f6e6473SBarry Smith prhs[4] = sctx->ctx; 4123b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 4124e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4125e650e774SBarry Smith mxDestroyArray(prhs[0]); 4126e650e774SBarry Smith mxDestroyArray(prhs[1]); 4127e650e774SBarry Smith mxDestroyArray(prhs[2]); 41288f6e6473SBarry Smith mxDestroyArray(prhs[3]); 4129e650e774SBarry Smith mxDestroyArray(plhs[0]); 41300807856dSBarry Smith PetscFunctionReturn(0); 41310807856dSBarry Smith } 41320807856dSBarry Smith 41330807856dSBarry Smith 41340807856dSBarry Smith #undef __FUNCT__ 41350807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 413661b2408cSBarry Smith /* 41370807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 41380807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4139e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 41400807856dSBarry Smith 41410807856dSBarry Smith Logically Collective on SNES 41420807856dSBarry Smith 41430807856dSBarry Smith Input Parameters: 41440807856dSBarry Smith + snes - the SNES context 41450807856dSBarry Smith . r - vector to store function value 41460807856dSBarry Smith - func - function evaluation routine 41470807856dSBarry Smith 41480807856dSBarry Smith Calling sequence of func: 414961b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 41500807856dSBarry Smith 41510807856dSBarry Smith 41520807856dSBarry Smith Notes: 41530807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 41540807856dSBarry Smith $ f'(x) x = -f(x), 41550807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 41560807856dSBarry Smith 41570807856dSBarry Smith Level: beginner 41580807856dSBarry Smith 41590807856dSBarry Smith .keywords: SNES, nonlinear, set, function 41600807856dSBarry Smith 41610807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 416261b2408cSBarry Smith */ 41637087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 41640807856dSBarry Smith { 41650807856dSBarry Smith PetscErrorCode ierr; 41668f6e6473SBarry Smith SNESMatlabContext *sctx; 41670807856dSBarry Smith 41680807856dSBarry Smith PetscFunctionBegin; 41698f6e6473SBarry Smith /* currently sctx is memory bleed */ 41708f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 41718f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 41728f6e6473SBarry Smith /* 41738f6e6473SBarry Smith This should work, but it doesn't 41748f6e6473SBarry Smith sctx->ctx = ctx; 41758f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 41768f6e6473SBarry Smith */ 41778f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 41788f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 41790807856dSBarry Smith PetscFunctionReturn(0); 41800807856dSBarry Smith } 418169b4f73cSBarry Smith 418261b2408cSBarry Smith #undef __FUNCT__ 418361b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 418461b2408cSBarry Smith /* 418561b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 418661b2408cSBarry Smith SNESSetJacobianMatlab(). 418761b2408cSBarry Smith 418861b2408cSBarry Smith Collective on SNES 418961b2408cSBarry Smith 419061b2408cSBarry Smith Input Parameters: 419161b2408cSBarry Smith + snes - the SNES context 419261b2408cSBarry Smith . x - input vector 419361b2408cSBarry Smith . A, B - the matrices 419461b2408cSBarry Smith - ctx - user context 419561b2408cSBarry Smith 419661b2408cSBarry Smith Output Parameter: 419761b2408cSBarry Smith . flag - structure of the matrix 419861b2408cSBarry Smith 419961b2408cSBarry Smith Level: developer 420061b2408cSBarry Smith 420161b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 420261b2408cSBarry Smith 420361b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 420461b2408cSBarry Smith @*/ 42057087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 420661b2408cSBarry Smith { 420761b2408cSBarry Smith PetscErrorCode ierr; 420861b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 420961b2408cSBarry Smith int nlhs = 2,nrhs = 6; 421061b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 421161b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 421261b2408cSBarry Smith 421361b2408cSBarry Smith PetscFunctionBegin; 421461b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 421561b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 421661b2408cSBarry Smith 421761b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 421861b2408cSBarry Smith 421961b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 422061b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 422161b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 422261b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 422361b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 422461b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 422561b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 422661b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 422761b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 422861b2408cSBarry Smith prhs[5] = sctx->ctx; 4229b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 423061b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 423161b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 423261b2408cSBarry Smith mxDestroyArray(prhs[0]); 423361b2408cSBarry Smith mxDestroyArray(prhs[1]); 423461b2408cSBarry Smith mxDestroyArray(prhs[2]); 423561b2408cSBarry Smith mxDestroyArray(prhs[3]); 423661b2408cSBarry Smith mxDestroyArray(prhs[4]); 423761b2408cSBarry Smith mxDestroyArray(plhs[0]); 423861b2408cSBarry Smith mxDestroyArray(plhs[1]); 423961b2408cSBarry Smith PetscFunctionReturn(0); 424061b2408cSBarry Smith } 424161b2408cSBarry Smith 424261b2408cSBarry Smith 424361b2408cSBarry Smith #undef __FUNCT__ 424461b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 424561b2408cSBarry Smith /* 424661b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 424761b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4248e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 424961b2408cSBarry Smith 425061b2408cSBarry Smith Logically Collective on SNES 425161b2408cSBarry Smith 425261b2408cSBarry Smith Input Parameters: 425361b2408cSBarry Smith + snes - the SNES context 425461b2408cSBarry Smith . A,B - Jacobian matrices 425561b2408cSBarry Smith . func - function evaluation routine 425661b2408cSBarry Smith - ctx - user context 425761b2408cSBarry Smith 425861b2408cSBarry Smith Calling sequence of func: 425961b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 426061b2408cSBarry Smith 426161b2408cSBarry Smith 426261b2408cSBarry Smith Level: developer 426361b2408cSBarry Smith 426461b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 426561b2408cSBarry Smith 426661b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 426761b2408cSBarry Smith */ 42687087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 426961b2408cSBarry Smith { 427061b2408cSBarry Smith PetscErrorCode ierr; 427161b2408cSBarry Smith SNESMatlabContext *sctx; 427261b2408cSBarry Smith 427361b2408cSBarry Smith PetscFunctionBegin; 427461b2408cSBarry Smith /* currently sctx is memory bleed */ 427561b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 427661b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 427761b2408cSBarry Smith /* 427861b2408cSBarry Smith This should work, but it doesn't 427961b2408cSBarry Smith sctx->ctx = ctx; 428061b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 428161b2408cSBarry Smith */ 428261b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 428361b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 428461b2408cSBarry Smith PetscFunctionReturn(0); 428561b2408cSBarry Smith } 428669b4f73cSBarry Smith 4287f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4288f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4289f9eb7ae2SShri Abhyankar /* 4290f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4291f9eb7ae2SShri Abhyankar 4292f9eb7ae2SShri Abhyankar Collective on SNES 4293f9eb7ae2SShri Abhyankar 4294f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4295f9eb7ae2SShri Abhyankar @*/ 42967087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4297f9eb7ae2SShri Abhyankar { 4298f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 429948f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4300f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4301f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4302f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4303f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4304f9eb7ae2SShri Abhyankar 4305f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4306f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4307f9eb7ae2SShri Abhyankar 4308f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4309f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4310f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4311f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4312f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4313f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4314f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4315f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4316f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4317f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4318f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4319f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4320f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4321f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4322f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4323f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4324f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4325f9eb7ae2SShri Abhyankar } 4326f9eb7ae2SShri Abhyankar 4327f9eb7ae2SShri Abhyankar 4328f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4329f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4330f9eb7ae2SShri Abhyankar /* 4331e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4332f9eb7ae2SShri Abhyankar 4333f9eb7ae2SShri Abhyankar Level: developer 4334f9eb7ae2SShri Abhyankar 4335f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4336f9eb7ae2SShri Abhyankar 4337f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4338f9eb7ae2SShri Abhyankar */ 43397087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4340f9eb7ae2SShri Abhyankar { 4341f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4342f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4343f9eb7ae2SShri Abhyankar 4344f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4345f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4346f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4347f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4348f9eb7ae2SShri Abhyankar /* 4349f9eb7ae2SShri Abhyankar This should work, but it doesn't 4350f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4351f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4352f9eb7ae2SShri Abhyankar */ 4353f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4354f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4355f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4356f9eb7ae2SShri Abhyankar } 4357f9eb7ae2SShri Abhyankar 435869b4f73cSBarry Smith #endif 4359