1af0996ceSBarry Smith #include <petsc/private/snesimpl.h> /*I "petscsnes.h" I*/ 207475bc1SBarry Smith #include <petscdmshell.h> 3d96771aaSLisandro Dalcin #include <petscdraw.h> 4a01aa210SMatthew G. Knepley #include <petscds.h> 534b4d3a8SMatthew G. Knepley #include <petscdmadaptor.h> 606fc46c8SMatthew G. Knepley #include <petscconvest.h> 79b94acceSBarry Smith 8ace3abfcSBarry Smith PetscBool SNESRegisterAllCalled = PETSC_FALSE; 90298fd71SBarry Smith PetscFunctionList SNESList = NULL; 108ba1e511SMatthew Knepley 118ba1e511SMatthew Knepley /* Logging support */ 1222c6f798SBarry Smith PetscClassId SNES_CLASSID, DMSNES_CLASSID; 13e3ed9ee7SBarry Smith PetscLogEvent SNES_Solve, SNES_Setup, SNES_FunctionEval, SNES_JacobianEval, SNES_NGSEval, SNES_NGSFuncEval, SNES_NPCSolve, SNES_ObjectiveEval; 14a09944afSBarry Smith 15e113a28aSBarry Smith /*@ 16e113a28aSBarry Smith SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged. 17e113a28aSBarry Smith 183f9fe445SBarry Smith Logically Collective on SNES 19e113a28aSBarry Smith 20e113a28aSBarry Smith Input Parameters: 21e113a28aSBarry Smith + snes - iterative context obtained from SNESCreate() 22e113a28aSBarry Smith - flg - PETSC_TRUE indicates you want the error generated 23e113a28aSBarry Smith 24e113a28aSBarry Smith Options database keys: 25e113a28aSBarry Smith . -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false) 26e113a28aSBarry Smith 27e113a28aSBarry Smith Level: intermediate 28e113a28aSBarry Smith 29e113a28aSBarry Smith Notes: 30e113a28aSBarry Smith Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve() 31e113a28aSBarry Smith to determine if it has converged. 32e113a28aSBarry Smith 334d651a51SPierre Jolivet .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIfNotConverged() 34e113a28aSBarry Smith @*/ 357087cfbeSBarry Smith PetscErrorCode SNESSetErrorIfNotConverged(SNES snes,PetscBool flg) 36e113a28aSBarry Smith { 37e113a28aSBarry Smith PetscFunctionBegin; 38e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 39acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flg,2); 40e113a28aSBarry Smith snes->errorifnotconverged = flg; 41e113a28aSBarry Smith PetscFunctionReturn(0); 42e113a28aSBarry Smith } 43e113a28aSBarry Smith 44e113a28aSBarry Smith /*@ 45e113a28aSBarry Smith SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge? 46e113a28aSBarry Smith 47e113a28aSBarry Smith Not Collective 48e113a28aSBarry Smith 49e113a28aSBarry Smith Input Parameter: 50e113a28aSBarry Smith . snes - iterative context obtained from SNESCreate() 51e113a28aSBarry Smith 52e113a28aSBarry Smith Output Parameter: 53e113a28aSBarry Smith . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE 54e113a28aSBarry Smith 55e113a28aSBarry Smith Level: intermediate 56e113a28aSBarry Smith 574d651a51SPierre Jolivet .seealso: SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIfNotConverged() 58e113a28aSBarry Smith @*/ 597087cfbeSBarry Smith PetscErrorCode SNESGetErrorIfNotConverged(SNES snes,PetscBool *flag) 60e113a28aSBarry Smith { 61e113a28aSBarry Smith PetscFunctionBegin; 62e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 63534a8f05SLisandro Dalcin PetscValidBoolPointer(flag,2); 64e113a28aSBarry Smith *flag = snes->errorifnotconverged; 65e113a28aSBarry Smith PetscFunctionReturn(0); 66e113a28aSBarry Smith } 67e113a28aSBarry Smith 684fc747eaSLawrence Mitchell /*@ 694fc747eaSLawrence Mitchell SNESSetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution? 704fc747eaSLawrence Mitchell 714fc747eaSLawrence Mitchell Logically Collective on SNES 724fc747eaSLawrence Mitchell 734fc747eaSLawrence Mitchell Input Parameters: 744fc747eaSLawrence Mitchell + snes - the shell SNES 754fc747eaSLawrence Mitchell - flg - is the residual computed? 764fc747eaSLawrence Mitchell 774fc747eaSLawrence Mitchell Level: advanced 784fc747eaSLawrence Mitchell 794fc747eaSLawrence Mitchell .seealso: SNESGetAlwaysComputesFinalResidual() 804fc747eaSLawrence Mitchell @*/ 814fc747eaSLawrence Mitchell PetscErrorCode SNESSetAlwaysComputesFinalResidual(SNES snes, PetscBool flg) 824fc747eaSLawrence Mitchell { 834fc747eaSLawrence Mitchell PetscFunctionBegin; 844fc747eaSLawrence Mitchell PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 854fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = flg; 864fc747eaSLawrence Mitchell PetscFunctionReturn(0); 874fc747eaSLawrence Mitchell } 884fc747eaSLawrence Mitchell 894fc747eaSLawrence Mitchell /*@ 904fc747eaSLawrence Mitchell SNESGetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution? 914fc747eaSLawrence Mitchell 924fc747eaSLawrence Mitchell Logically Collective on SNES 934fc747eaSLawrence Mitchell 944fc747eaSLawrence Mitchell Input Parameter: 954fc747eaSLawrence Mitchell . snes - the shell SNES 964fc747eaSLawrence Mitchell 974fc747eaSLawrence Mitchell Output Parameter: 984fc747eaSLawrence Mitchell . flg - is the residual computed? 994fc747eaSLawrence Mitchell 1004fc747eaSLawrence Mitchell Level: advanced 1014fc747eaSLawrence Mitchell 1024fc747eaSLawrence Mitchell .seealso: SNESSetAlwaysComputesFinalResidual() 1034fc747eaSLawrence Mitchell @*/ 1044fc747eaSLawrence Mitchell PetscErrorCode SNESGetAlwaysComputesFinalResidual(SNES snes, PetscBool *flg) 1054fc747eaSLawrence Mitchell { 1064fc747eaSLawrence Mitchell PetscFunctionBegin; 1074fc747eaSLawrence Mitchell PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1084fc747eaSLawrence Mitchell *flg = snes->alwayscomputesfinalresidual; 1094fc747eaSLawrence Mitchell PetscFunctionReturn(0); 1104fc747eaSLawrence Mitchell } 1114fc747eaSLawrence Mitchell 112e725d27bSBarry Smith /*@ 113bf388a1fSBarry Smith SNESSetFunctionDomainError - tells SNES that the input vector to your SNESFunction is not 1144936397dSBarry Smith in the functions domain. For example, negative pressure. 1154936397dSBarry Smith 1163f9fe445SBarry Smith Logically Collective on SNES 1174936397dSBarry Smith 1184936397dSBarry Smith Input Parameters: 1196a388c36SPeter Brune . snes - the SNES context 1204936397dSBarry Smith 12128529972SSatish Balay Level: advanced 1224936397dSBarry Smith 123bf388a1fSBarry Smith .seealso: SNESCreate(), SNESSetFunction(), SNESFunction 1244936397dSBarry Smith @*/ 1257087cfbeSBarry Smith PetscErrorCode SNESSetFunctionDomainError(SNES snes) 1264936397dSBarry Smith { 1274936397dSBarry Smith PetscFunctionBegin; 1280700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 129422a814eSBarry Smith if (snes->errorifnotconverged) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"User code indicates input vector is not in the function domain"); 1304936397dSBarry Smith snes->domainerror = PETSC_TRUE; 1314936397dSBarry Smith PetscFunctionReturn(0); 1324936397dSBarry Smith } 1334936397dSBarry Smith 1346a388c36SPeter Brune /*@ 13507b62357SFande Kong SNESSetJacobianDomainError - tells SNES that computeJacobian does not make sense any more. For example there is a negative element transformation. 13607b62357SFande Kong 13707b62357SFande Kong Logically Collective on SNES 13807b62357SFande Kong 13907b62357SFande Kong Input Parameters: 14007b62357SFande Kong . snes - the SNES context 14107b62357SFande Kong 14207b62357SFande Kong Level: advanced 14307b62357SFande Kong 14407b62357SFande Kong .seealso: SNESCreate(), SNESSetFunction(), SNESFunction(), SNESSetFunctionDomainError() 14507b62357SFande Kong @*/ 14607b62357SFande Kong PetscErrorCode SNESSetJacobianDomainError(SNES snes) 14707b62357SFande Kong { 14807b62357SFande Kong PetscFunctionBegin; 14907b62357SFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15007b62357SFande Kong if (snes->errorifnotconverged) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"User code indicates computeJacobian does not make sense"); 15107b62357SFande Kong snes->jacobiandomainerror = PETSC_TRUE; 15207b62357SFande Kong PetscFunctionReturn(0); 15307b62357SFande Kong } 15407b62357SFande Kong 15507b62357SFande Kong /*@ 156b351a90bSFande Kong SNESSetCheckJacobianDomainError - if or not to check jacobian domain error after each Jacobian evaluation. By default, we check Jacobian domain error 157b351a90bSFande Kong in the debug mode, and do not check it in the optimized mode. 158b351a90bSFande Kong 159b351a90bSFande Kong Logically Collective on SNES 160b351a90bSFande Kong 161b351a90bSFande Kong Input Parameters: 162a2b725a8SWilliam Gropp + snes - the SNES context 163a2b725a8SWilliam Gropp - flg - indicates if or not to check jacobian domain error after each Jacobian evaluation 164b351a90bSFande Kong 165b351a90bSFande Kong Level: advanced 166b351a90bSFande Kong 1678383d7d7SFande Kong .seealso: SNESCreate(), SNESSetFunction(), SNESFunction(), SNESSetFunctionDomainError(), SNESGetCheckJacobianDomainError() 168b351a90bSFande Kong @*/ 169b351a90bSFande Kong PetscErrorCode SNESSetCheckJacobianDomainError(SNES snes, PetscBool flg) 170b351a90bSFande Kong { 171b351a90bSFande Kong PetscFunctionBegin; 172b351a90bSFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 173b351a90bSFande Kong snes->checkjacdomainerror = flg; 174b351a90bSFande Kong PetscFunctionReturn(0); 175b351a90bSFande Kong } 176b351a90bSFande Kong 177b351a90bSFande Kong /*@ 1788383d7d7SFande Kong SNESGetCheckJacobianDomainError - Get an indicator whether or not we are checking Jacobian domain errors after each Jacobian evaluation. 1798383d7d7SFande Kong 1808383d7d7SFande Kong Logically Collective on SNES 1818383d7d7SFande Kong 1828383d7d7SFande Kong Input Parameters: 1838383d7d7SFande Kong . snes - the SNES context 1848383d7d7SFande Kong 1858383d7d7SFande Kong Output Parameters: 1868383d7d7SFande Kong . flg - PETSC_FALSE indicates that we don't check jacobian domain errors after each Jacobian evaluation 1878383d7d7SFande Kong 1888383d7d7SFande Kong Level: advanced 1898383d7d7SFande Kong 1908383d7d7SFande Kong .seealso: SNESCreate(), SNESSetFunction(), SNESFunction(), SNESSetFunctionDomainError(), SNESSetCheckJacobianDomainError() 1918383d7d7SFande Kong @*/ 1928383d7d7SFande Kong PetscErrorCode SNESGetCheckJacobianDomainError(SNES snes, PetscBool *flg) 1938383d7d7SFande Kong { 1948383d7d7SFande Kong PetscFunctionBegin; 1958383d7d7SFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 196534a8f05SLisandro Dalcin PetscValidBoolPointer(flg,2); 1978383d7d7SFande Kong *flg = snes->checkjacdomainerror; 1988383d7d7SFande Kong PetscFunctionReturn(0); 1998383d7d7SFande Kong } 2008383d7d7SFande Kong 2018383d7d7SFande Kong /*@ 202c77b2880SPeter Brune SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction; 2036a388c36SPeter Brune 2046a388c36SPeter Brune Logically Collective on SNES 2056a388c36SPeter Brune 2066a388c36SPeter Brune Input Parameters: 2076a388c36SPeter Brune . snes - the SNES context 2086a388c36SPeter Brune 2096a388c36SPeter Brune Output Parameters: 210bf388a1fSBarry Smith . domainerror - Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise. 2116a388c36SPeter Brune 2126a388c36SPeter Brune Level: advanced 2136a388c36SPeter Brune 214bf388a1fSBarry Smith .seealso: SNESSetFunctionDomainError(), SNESComputeFunction() 2156a388c36SPeter Brune @*/ 2166a388c36SPeter Brune PetscErrorCode SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror) 2176a388c36SPeter Brune { 2186a388c36SPeter Brune PetscFunctionBegin; 2196a388c36SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 220534a8f05SLisandro Dalcin PetscValidBoolPointer(domainerror,2); 2216a388c36SPeter Brune *domainerror = snes->domainerror; 2226a388c36SPeter Brune PetscFunctionReturn(0); 2236a388c36SPeter Brune } 2246a388c36SPeter Brune 22507b62357SFande Kong /*@ 22607b62357SFande Kong SNESGetJacobianDomainError - Gets the status of the Jacobian domain error after a call to SNESComputeJacobian; 22707b62357SFande Kong 22807b62357SFande Kong Logically Collective on SNES 22907b62357SFande Kong 23007b62357SFande Kong Input Parameters: 23107b62357SFande Kong . snes - the SNES context 23207b62357SFande Kong 23307b62357SFande Kong Output Parameters: 23407b62357SFande Kong . domainerror - Set to PETSC_TRUE if there's a jacobian domain error; PETSC_FALSE otherwise. 23507b62357SFande Kong 23607b62357SFande Kong Level: advanced 23707b62357SFande Kong 23807b62357SFande Kong .seealso: SNESSetFunctionDomainError(), SNESComputeFunction(),SNESGetFunctionDomainError() 23907b62357SFande Kong @*/ 24007b62357SFande Kong PetscErrorCode SNESGetJacobianDomainError(SNES snes, PetscBool *domainerror) 24107b62357SFande Kong { 24207b62357SFande Kong PetscFunctionBegin; 24307b62357SFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 244534a8f05SLisandro Dalcin PetscValidBoolPointer(domainerror,2); 24507b62357SFande Kong *domainerror = snes->jacobiandomainerror; 24607b62357SFande Kong PetscFunctionReturn(0); 24707b62357SFande Kong } 24807b62357SFande Kong 24955849f57SBarry Smith /*@C 25055849f57SBarry Smith SNESLoad - Loads a SNES that has been stored in binary with SNESView(). 25155849f57SBarry Smith 25255849f57SBarry Smith Collective on PetscViewer 25355849f57SBarry Smith 25455849f57SBarry Smith Input Parameters: 25555849f57SBarry Smith + newdm - the newly loaded SNES, this needs to have been created with SNESCreate() or 25655849f57SBarry Smith some related function before a call to SNESLoad(). 25755849f57SBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() 25855849f57SBarry Smith 25955849f57SBarry Smith Level: intermediate 26055849f57SBarry Smith 26155849f57SBarry Smith Notes: 26255849f57SBarry Smith The type is determined by the data in the file, any type set into the SNES before this call is ignored. 26355849f57SBarry Smith 26455849f57SBarry Smith Notes for advanced users: 26555849f57SBarry Smith Most users should not need to know the details of the binary storage 26655849f57SBarry Smith format, since SNESLoad() and TSView() completely hide these details. 26755849f57SBarry Smith But for anyone who's interested, the standard binary matrix storage 26855849f57SBarry Smith format is 26955849f57SBarry Smith .vb 27055849f57SBarry Smith has not yet been determined 27155849f57SBarry Smith .ve 27255849f57SBarry Smith 27355849f57SBarry Smith .seealso: PetscViewerBinaryOpen(), SNESView(), MatLoad(), VecLoad() 27455849f57SBarry Smith @*/ 2752d53ad75SBarry Smith PetscErrorCode SNESLoad(SNES snes, PetscViewer viewer) 27655849f57SBarry Smith { 27755849f57SBarry Smith PetscErrorCode ierr; 27855849f57SBarry Smith PetscBool isbinary; 279060da220SMatthew G. Knepley PetscInt classid; 28055849f57SBarry Smith char type[256]; 28155849f57SBarry Smith KSP ksp; 2822d53ad75SBarry Smith DM dm; 2832d53ad75SBarry Smith DMSNES dmsnes; 28455849f57SBarry Smith 28555849f57SBarry Smith PetscFunctionBegin; 2862d53ad75SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 28755849f57SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 28855849f57SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 28955849f57SBarry Smith if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 29055849f57SBarry Smith 291060da220SMatthew G. Knepley ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr); 292ce94432eSBarry Smith if (classid != SNES_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONG,"Not SNES next in file"); 293060da220SMatthew G. Knepley ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr); 2942d53ad75SBarry Smith ierr = SNESSetType(snes, type);CHKERRQ(ierr); 2952d53ad75SBarry Smith if (snes->ops->load) { 2962d53ad75SBarry Smith ierr = (*snes->ops->load)(snes,viewer);CHKERRQ(ierr); 297f2c2a1b9SBarry Smith } 2982d53ad75SBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2992d53ad75SBarry Smith ierr = DMGetDMSNES(dm,&dmsnes);CHKERRQ(ierr); 3002d53ad75SBarry Smith ierr = DMSNESLoad(dmsnes,viewer);CHKERRQ(ierr); 3012d53ad75SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 30255849f57SBarry Smith ierr = KSPLoad(ksp,viewer);CHKERRQ(ierr); 30355849f57SBarry Smith PetscFunctionReturn(0); 30455849f57SBarry Smith } 3056a388c36SPeter Brune 3069804daf3SBarry Smith #include <petscdraw.h> 307e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 308e04113cfSBarry Smith #include <petscviewersaws.h> 309bfb97211SBarry Smith #endif 3108404b7f3SBarry Smith 311fe2efc57SMark /*@C 312fe2efc57SMark SNESViewFromOptions - View from Options 313fe2efc57SMark 314fe2efc57SMark Collective on SNES 315fe2efc57SMark 316fe2efc57SMark Input Parameters: 317fe2efc57SMark + A - the application ordering context 318736c3998SJose E. Roman . obj - Optional object 319736c3998SJose E. Roman - name - command line option 320fe2efc57SMark 321fe2efc57SMark Level: intermediate 322fe2efc57SMark .seealso: SNES, SNESView, PetscObjectViewFromOptions(), SNESCreate() 323fe2efc57SMark @*/ 324fe2efc57SMark PetscErrorCode SNESViewFromOptions(SNES A,PetscObject obj,const char name[]) 325fe2efc57SMark { 326fe2efc57SMark PetscErrorCode ierr; 327fe2efc57SMark 328fe2efc57SMark PetscFunctionBegin; 329fe2efc57SMark PetscValidHeaderSpecific(A,SNES_CLASSID,1); 330fe2efc57SMark ierr = PetscObjectViewFromOptions((PetscObject)A,obj,name);CHKERRQ(ierr); 331fe2efc57SMark PetscFunctionReturn(0); 332fe2efc57SMark } 333fe2efc57SMark 334789d8953SBarry Smith PETSC_EXTERN PetscErrorCode SNESComputeJacobian_DMDA(SNES,Vec,Mat,Mat,void*); 335789d8953SBarry Smith 3367e2c5f70SBarry Smith /*@C 3379b94acceSBarry Smith SNESView - Prints the SNES data structure. 3389b94acceSBarry Smith 3394c49b128SBarry Smith Collective on SNES 340fee21e36SBarry Smith 341c7afd0dbSLois Curfman McInnes Input Parameters: 342c7afd0dbSLois Curfman McInnes + SNES - the SNES context 343c7afd0dbSLois Curfman McInnes - viewer - visualization context 344c7afd0dbSLois Curfman McInnes 3459b94acceSBarry Smith Options Database Key: 346c8a8ba5cSLois Curfman McInnes . -snes_view - Calls SNESView() at end of SNESSolve() 3479b94acceSBarry Smith 3489b94acceSBarry Smith Notes: 3499b94acceSBarry Smith The available visualization contexts include 350b0a32e0cSBarry Smith + PETSC_VIEWER_STDOUT_SELF - standard output (default) 351b0a32e0cSBarry Smith - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 352c8a8ba5cSLois Curfman McInnes output where only the first processor opens 353c8a8ba5cSLois Curfman McInnes the file. All other processors send their 354c8a8ba5cSLois Curfman McInnes data to the first processor to print. 3559b94acceSBarry Smith 356052bf0daSPierre Jolivet The available formats include 357052bf0daSPierre Jolivet + PETSC_VIEWER_DEFAULT - standard output (default) 358052bf0daSPierre Jolivet - PETSC_VIEWER_ASCII_INFO_DETAIL - more verbose output for SNESNASM 359052bf0daSPierre Jolivet 3603e081fefSLois Curfman McInnes The user can open an alternative visualization context with 361b0a32e0cSBarry Smith PetscViewerASCIIOpen() - output to a specified file. 3629b94acceSBarry Smith 363595c91d4SBarry Smith In the debugger you can do "call SNESView(snes,0)" to display the SNES solver. (The same holds for any PETSc object viewer). 364595c91d4SBarry Smith 36536851e7fSLois Curfman McInnes Level: beginner 36636851e7fSLois Curfman McInnes 367b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen() 3689b94acceSBarry Smith @*/ 3697087cfbeSBarry Smith PetscErrorCode SNESView(SNES snes,PetscViewer viewer) 3709b94acceSBarry Smith { 371fa9f3622SBarry Smith SNESKSPEW *kctx; 372dfbe8321SBarry Smith PetscErrorCode ierr; 37394b7f48cSBarry Smith KSP ksp; 3747f1410a3SPeter Brune SNESLineSearch linesearch; 37572a02f06SBarry Smith PetscBool iascii,isstring,isbinary,isdraw; 3762d53ad75SBarry Smith DMSNES dmsnes; 377e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 378536b137fSBarry Smith PetscBool issaws; 379bfb97211SBarry Smith #endif 3809b94acceSBarry Smith 3813a40ed3dSBarry Smith PetscFunctionBegin; 3820700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3833050cee2SBarry Smith if (!viewer) { 384ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&viewer);CHKERRQ(ierr); 3853050cee2SBarry Smith } 3860700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 387c9780b6fSBarry Smith PetscCheckSameComm(snes,1,viewer,2); 38874679c65SBarry Smith 389251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 390251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 39155849f57SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 39272a02f06SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 393e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 394536b137fSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 395bfb97211SBarry Smith #endif 39632077d6dSBarry Smith if (iascii) { 397dc0571f2SMatthew G. Knepley SNESNormSchedule normschedule; 3988404b7f3SBarry Smith DM dm; 3998404b7f3SBarry Smith PetscErrorCode (*cJ)(SNES,Vec,Mat,Mat,void*); 4008404b7f3SBarry Smith void *ctx; 401789d8953SBarry Smith const char *pre = ""; 402dc0571f2SMatthew G. Knepley 403dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer);CHKERRQ(ierr); 404fce1e034SJed Brown if (!snes->setupcalled) { 405fce1e034SJed Brown ierr = PetscViewerASCIIPrintf(viewer," SNES has not been set up so information may be incomplete\n");CHKERRQ(ierr); 406fce1e034SJed Brown } 407e7788613SBarry Smith if (snes->ops->view) { 408b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 409e7788613SBarry Smith ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 410b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 4110ef38995SBarry Smith } 41277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr); 41357622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%g, absolute=%g, solution=%g\n",(double)snes->rtol,(double)snes->abstol,(double)snes->stol);CHKERRQ(ierr); 414efd4aadfSBarry Smith if (snes->usesksp) { 41577431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr); 416efd4aadfSBarry Smith } 41777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr); 418dc0571f2SMatthew G. Knepley ierr = SNESGetNormSchedule(snes, &normschedule);CHKERRQ(ierr); 419dc0571f2SMatthew G. Knepley if (normschedule > 0) {ierr = PetscViewerASCIIPrintf(viewer," norm schedule %s\n",SNESNormSchedules[normschedule]);CHKERRQ(ierr);} 42017fe4bdfSPeter Brune if (snes->gridsequence) { 42117fe4bdfSPeter Brune ierr = PetscViewerASCIIPrintf(viewer," total number of grid sequence refinements=%D\n",snes->gridsequence);CHKERRQ(ierr); 42217fe4bdfSPeter Brune } 4239b94acceSBarry Smith if (snes->ksp_ewconv) { 424fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4259b94acceSBarry Smith if (kctx) { 42677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr); 42757622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," rtol_0=%g, rtol_max=%g, threshold=%g\n",(double)kctx->rtol_0,(double)kctx->rtol_max,(double)kctx->threshold);CHKERRQ(ierr); 42857622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," gamma=%g, alpha=%g, alpha2=%g\n",(double)kctx->gamma,(double)kctx->alpha,(double)kctx->alpha2);CHKERRQ(ierr); 4299b94acceSBarry Smith } 4309b94acceSBarry Smith } 431eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 432eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n");CHKERRQ(ierr); 433eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 434eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr); 435eb1f6c34SBarry Smith } 436eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 437eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n");CHKERRQ(ierr); 438eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 43942f4f86dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr); 440eb1f6c34SBarry Smith } 4418404b7f3SBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4428404b7f3SBarry Smith ierr = DMSNESGetJacobian(dm,&cJ,&ctx);CHKERRQ(ierr); 443789d8953SBarry Smith if (snes->mf_operator) { 444789d8953SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is applied matrix-free with differencing\n");CHKERRQ(ierr); 445789d8953SBarry Smith pre = "Preconditioning "; 446789d8953SBarry Smith } 4478404b7f3SBarry Smith if (cJ == SNESComputeJacobianDefault) { 448789d8953SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %sJacobian is built using finite differences one column at a time\n",pre);CHKERRQ(ierr); 4498404b7f3SBarry Smith } else if (cJ == SNESComputeJacobianDefaultColor) { 450789d8953SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %sJacobian is built using finite differences with coloring\n",pre);CHKERRQ(ierr); 451789d8953SBarry Smith /* it slightly breaks data encapsulation for access the DMDA information directly */ 452789d8953SBarry Smith } else if (cJ == SNESComputeJacobian_DMDA) { 453789d8953SBarry Smith MatFDColoring fdcoloring; 454789d8953SBarry Smith ierr = PetscObjectQuery((PetscObject)dm,"DMDASNES_FDCOLORING",(PetscObject*)&fdcoloring);CHKERRQ(ierr); 455789d8953SBarry Smith if (fdcoloring) { 456789d8953SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %sJacobian is built using colored finite differences on a DMDA\n",pre);CHKERRQ(ierr); 457789d8953SBarry Smith } else { 458789d8953SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %sJacobian is built using a DMDA local Jacobian\n",pre);CHKERRQ(ierr); 459789d8953SBarry Smith } 460789d8953SBarry Smith } else if (snes->mf) { 461a5b23f4aSJose E. Roman ierr = PetscViewerASCIIPrintf(viewer," Jacobian is applied matrix-free with differencing, no explicit Jacobian\n");CHKERRQ(ierr); 4628404b7f3SBarry Smith } 4630f5bd95cSBarry Smith } else if (isstring) { 464317d6ea6SBarry Smith const char *type; 465454a90a3SBarry Smith ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 46636a9e3b9SBarry Smith ierr = PetscViewerStringSPrintf(viewer," SNESType: %-7.7s",type);CHKERRQ(ierr); 46736a9e3b9SBarry Smith if (snes->ops->view) {ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);} 46855849f57SBarry Smith } else if (isbinary) { 46955849f57SBarry Smith PetscInt classid = SNES_FILE_CLASSID; 47055849f57SBarry Smith MPI_Comm comm; 47155849f57SBarry Smith PetscMPIInt rank; 47255849f57SBarry Smith char type[256]; 47355849f57SBarry Smith 47455849f57SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 475ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 476dd400576SPatrick Sanan if (rank == 0) { 477f253e43cSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT);CHKERRQ(ierr); 47889d949e2SBarry Smith ierr = PetscStrncpy(type,((PetscObject)snes)->type_name,sizeof(type));CHKERRQ(ierr); 479f253e43cSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,type,sizeof(type),PETSC_CHAR);CHKERRQ(ierr); 48055849f57SBarry Smith } 48155849f57SBarry Smith if (snes->ops->view) { 48255849f57SBarry Smith ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 48355849f57SBarry Smith } 48472a02f06SBarry Smith } else if (isdraw) { 48572a02f06SBarry Smith PetscDraw draw; 48672a02f06SBarry Smith char str[36]; 48789fd9fafSBarry Smith PetscReal x,y,bottom,h; 48872a02f06SBarry Smith 48972a02f06SBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 49072a02f06SBarry Smith ierr = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr); 491a126751eSBarry Smith ierr = PetscStrncpy(str,"SNES: ",sizeof(str));CHKERRQ(ierr); 492a126751eSBarry Smith ierr = PetscStrlcat(str,((PetscObject)snes)->type_name,sizeof(str));CHKERRQ(ierr); 49351fa3d41SBarry Smith ierr = PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLUE,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr); 49489fd9fafSBarry Smith bottom = y - h; 49572a02f06SBarry Smith ierr = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr); 496c4646bacSPeter Brune if (snes->ops->view) { 497c4646bacSPeter Brune ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 498c4646bacSPeter Brune } 499e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 500536b137fSBarry Smith } else if (issaws) { 501d45a07a7SBarry Smith PetscMPIInt rank; 5022657e9d9SBarry Smith const char *name; 503d45a07a7SBarry Smith 5042657e9d9SBarry Smith ierr = PetscObjectGetName((PetscObject)snes,&name);CHKERRQ(ierr); 505ffc4695bSBarry Smith ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRMPI(ierr); 506dd400576SPatrick Sanan if (!((PetscObject)snes)->amsmem && rank == 0) { 507d45a07a7SBarry Smith char dir[1024]; 508d45a07a7SBarry Smith 509e04113cfSBarry Smith ierr = PetscObjectViewSAWs((PetscObject)snes,viewer);CHKERRQ(ierr); 5102657e9d9SBarry Smith ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/its",name);CHKERRQ(ierr); 5112657e9d9SBarry Smith PetscStackCallSAWs(SAWs_Register,(dir,&snes->iter,1,SAWs_READ,SAWs_INT)); 512bfb97211SBarry Smith if (!snes->conv_hist) { 513a0931e03SBarry Smith ierr = SNESSetConvergenceHistory(snes,NULL,NULL,PETSC_DECIDE,PETSC_TRUE);CHKERRQ(ierr); 514bfb97211SBarry Smith } 5152657e9d9SBarry Smith ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/conv_hist",name);CHKERRQ(ierr); 5162657e9d9SBarry Smith PetscStackCallSAWs(SAWs_Register,(dir,snes->conv_hist,10,SAWs_READ,SAWs_DOUBLE)); 517f05ece33SBarry Smith } 518bfb97211SBarry Smith #endif 51972a02f06SBarry Smith } 52072a02f06SBarry Smith if (snes->linesearch) { 5217601faf0SJed Brown ierr = SNESGetLineSearch(snes, &linesearch);CHKERRQ(ierr); 52285928a98SStefano Zampini ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 52372a02f06SBarry Smith ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr); 52485928a98SStefano Zampini ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 52519bcc07fSBarry Smith } 526efd4aadfSBarry Smith if (snes->npc && snes->usesnpc) { 52785928a98SStefano Zampini ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 528efd4aadfSBarry Smith ierr = SNESView(snes->npc, viewer);CHKERRQ(ierr); 52985928a98SStefano Zampini ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 5304a0c5b0cSMatthew G Knepley } 5312d53ad75SBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 5322d53ad75SBarry Smith ierr = DMGetDMSNES(snes->dm,&dmsnes);CHKERRQ(ierr); 5332d53ad75SBarry Smith ierr = DMSNESView(dmsnes, viewer);CHKERRQ(ierr); 5342d53ad75SBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 5352c155ee1SBarry Smith if (snes->usesksp) { 5362c155ee1SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 53785928a98SStefano Zampini ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 53894b7f48cSBarry Smith ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 53985928a98SStefano Zampini ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 5402c155ee1SBarry Smith } 54172a02f06SBarry Smith if (isdraw) { 54272a02f06SBarry Smith PetscDraw draw; 54372a02f06SBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 54472a02f06SBarry Smith ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr); 5457f1410a3SPeter Brune } 5463a40ed3dSBarry Smith PetscFunctionReturn(0); 5479b94acceSBarry Smith } 5489b94acceSBarry Smith 54976b2cf59SMatthew Knepley /* 55076b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 55176b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 55276b2cf59SMatthew Knepley */ 55376b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 554a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 5556849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 55676b2cf59SMatthew Knepley 557ac226902SBarry Smith /*@C 55876b2cf59SMatthew Knepley SNESAddOptionsChecker - Adds an additional function to check for SNES options. 55976b2cf59SMatthew Knepley 56076b2cf59SMatthew Knepley Not Collective 56176b2cf59SMatthew Knepley 56276b2cf59SMatthew Knepley Input Parameter: 56376b2cf59SMatthew Knepley . snescheck - function that checks for options 56476b2cf59SMatthew Knepley 56576b2cf59SMatthew Knepley Level: developer 56676b2cf59SMatthew Knepley 56776b2cf59SMatthew Knepley .seealso: SNESSetFromOptions() 56876b2cf59SMatthew Knepley @*/ 5697087cfbeSBarry Smith PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 57076b2cf59SMatthew Knepley { 57176b2cf59SMatthew Knepley PetscFunctionBegin; 572f23aa3ddSBarry Smith if (numberofsetfromoptions >= MAXSETFROMOPTIONS) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 57376b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 57476b2cf59SMatthew Knepley PetscFunctionReturn(0); 57576b2cf59SMatthew Knepley } 57676b2cf59SMatthew Knepley 57725acbd8eSLisandro Dalcin PETSC_INTERN PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 578aa3661deSLisandro Dalcin 579ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 580aa3661deSLisandro Dalcin { 581aa3661deSLisandro Dalcin Mat J; 582aa3661deSLisandro Dalcin PetscErrorCode ierr; 583895c21f2SBarry Smith MatNullSpace nullsp; 584aa3661deSLisandro Dalcin 585aa3661deSLisandro Dalcin PetscFunctionBegin; 5860700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 587aa3661deSLisandro Dalcin 58898613b67SLisandro Dalcin if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 58998613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 5902a7a6963SBarry Smith ierr = MatCreateVecs(A ? A : B, NULL,&snes->vec_func);CHKERRQ(ierr); 59198613b67SLisandro Dalcin } 59298613b67SLisandro Dalcin 593aa3661deSLisandro Dalcin if (version == 1) { 594aa3661deSLisandro Dalcin ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 59598613b67SLisandro Dalcin ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 5969c6ac3b3SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 597aa3661deSLisandro Dalcin } else if (version == 2) { 598e32f2f54SBarry Smith if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 599570b7f6dSBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FP16) 600aa3661deSLisandro Dalcin ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr); 601aa3661deSLisandro Dalcin #else 6022479783cSJose E. Roman SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator routines (version 2)"); 603aa3661deSLisandro Dalcin #endif 6042479783cSJose E. Roman } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator routines, only version 1 and 2"); 605aa3661deSLisandro Dalcin 606895c21f2SBarry Smith /* attach any user provided null space that was on Amat to the newly created matrix free matrix */ 607895c21f2SBarry Smith if (snes->jacobian) { 608895c21f2SBarry Smith ierr = MatGetNullSpace(snes->jacobian,&nullsp);CHKERRQ(ierr); 609895c21f2SBarry Smith if (nullsp) { 610895c21f2SBarry Smith ierr = MatSetNullSpace(J,nullsp);CHKERRQ(ierr); 611895c21f2SBarry Smith } 612895c21f2SBarry Smith } 613895c21f2SBarry Smith 614aa3661deSLisandro Dalcin ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr); 615d3462f78SMatthew Knepley if (hasOperator) { 6163232da50SPeter Brune 617aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 618aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 6199e5d0892SLisandro Dalcin ierr = SNESSetJacobian(snes,J,NULL,NULL,NULL);CHKERRQ(ierr); 620aa3661deSLisandro Dalcin } else { 621aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 6223232da50SPeter Brune provided preconditioner Jacobian with the default matrix free version. */ 623efd4aadfSBarry Smith if ((snes->npcside== PC_LEFT) && snes->npc) { 6249e5d0892SLisandro Dalcin if (!snes->jacobian) {ierr = SNESSetJacobian(snes,J,NULL,NULL,NULL);CHKERRQ(ierr);} 625172a4300SPeter Brune } else { 626789d8953SBarry Smith KSP ksp; 627789d8953SBarry Smith PC pc; 628789d8953SBarry Smith PetscBool match; 629789d8953SBarry Smith 6309e5d0892SLisandro Dalcin ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,NULL);CHKERRQ(ierr); 631aa3661deSLisandro Dalcin /* Force no preconditioner */ 632aa3661deSLisandro Dalcin ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 633aa3661deSLisandro Dalcin ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 634251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr); 635aa3661deSLisandro Dalcin if (!match) { 636aa3661deSLisandro Dalcin ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 637aa3661deSLisandro Dalcin ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 638aa3661deSLisandro Dalcin } 639aa3661deSLisandro Dalcin } 640789d8953SBarry Smith } 6416bf464f9SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 642aa3661deSLisandro Dalcin PetscFunctionReturn(0); 643aa3661deSLisandro Dalcin } 644aa3661deSLisandro Dalcin 645dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx) 646dfe15315SJed Brown { 647dfe15315SJed Brown SNES snes = (SNES)ctx; 648dfe15315SJed Brown PetscErrorCode ierr; 6490298fd71SBarry Smith Vec Xfine,Xfine_named = NULL,Xcoarse; 650dfe15315SJed Brown 651dfe15315SJed Brown PetscFunctionBegin; 65216ebb321SJed Brown if (PetscLogPrintInfo) { 65316ebb321SJed Brown PetscInt finelevel,coarselevel,fineclevel,coarseclevel; 65416ebb321SJed Brown ierr = DMGetRefineLevel(dmfine,&finelevel);CHKERRQ(ierr); 65516ebb321SJed Brown ierr = DMGetCoarsenLevel(dmfine,&fineclevel);CHKERRQ(ierr); 65616ebb321SJed Brown ierr = DMGetRefineLevel(dmcoarse,&coarselevel);CHKERRQ(ierr); 65716ebb321SJed Brown ierr = DMGetCoarsenLevel(dmcoarse,&coarseclevel);CHKERRQ(ierr); 65816ebb321SJed Brown ierr = PetscInfo4(dmfine,"Restricting SNES solution vector from level %D-%D to level %D-%D\n",finelevel,fineclevel,coarselevel,coarseclevel);CHKERRQ(ierr); 65916ebb321SJed Brown } 660dfe15315SJed Brown if (dmfine == snes->dm) Xfine = snes->vec_sol; 661dfe15315SJed Brown else { 662dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr); 663dfe15315SJed Brown Xfine = Xfine_named; 664dfe15315SJed Brown } 665dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 666907f5c5aSLawrence Mitchell if (Inject) { 667907f5c5aSLawrence Mitchell ierr = MatRestrict(Inject,Xfine,Xcoarse);CHKERRQ(ierr); 668907f5c5aSLawrence Mitchell } else { 669dfe15315SJed Brown ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr); 670dfe15315SJed Brown ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr); 671907f5c5aSLawrence Mitchell } 672dfe15315SJed Brown ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 673dfe15315SJed Brown if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);} 674dfe15315SJed Brown PetscFunctionReturn(0); 675dfe15315SJed Brown } 676dfe15315SJed Brown 67716ebb321SJed Brown static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx) 67816ebb321SJed Brown { 67916ebb321SJed Brown PetscErrorCode ierr; 68016ebb321SJed Brown 68116ebb321SJed Brown PetscFunctionBegin; 68216ebb321SJed Brown ierr = DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx);CHKERRQ(ierr); 68316ebb321SJed Brown PetscFunctionReturn(0); 68416ebb321SJed Brown } 68516ebb321SJed Brown 686a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can 687a6950cb2SJed Brown * safely call SNESGetDM() in their residual evaluation routine. */ 68823ee1639SBarry Smith static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,void *ctx) 689caa4e7f2SJed Brown { 690caa4e7f2SJed Brown SNES snes = (SNES)ctx; 691caa4e7f2SJed Brown PetscErrorCode ierr; 6920298fd71SBarry Smith Vec X,Xnamed = NULL; 693dfe15315SJed Brown DM dmsave; 6944e269d77SPeter Brune void *ctxsave; 69525ce1634SJed Brown PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*) = NULL; 696caa4e7f2SJed Brown 697caa4e7f2SJed Brown PetscFunctionBegin; 698dfe15315SJed Brown dmsave = snes->dm; 699dfe15315SJed Brown ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr); 700dfe15315SJed Brown if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */ 701dfe15315SJed Brown else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ 702dfe15315SJed Brown ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 703dfe15315SJed Brown X = Xnamed; 7040298fd71SBarry Smith ierr = SNESGetJacobian(snes,NULL,NULL,&jac,&ctxsave);CHKERRQ(ierr); 7054e269d77SPeter Brune /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */ 7068d359177SBarry Smith if (jac == SNESComputeJacobianDefaultColor) { 7079e5d0892SLisandro Dalcin ierr = SNESSetJacobian(snes,NULL,NULL,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr); 708dfe15315SJed Brown } 7094e269d77SPeter Brune } 7104dde8bb0SMatthew G. Knepley /* Make sure KSP DM has the Jacobian computation routine */ 7114dde8bb0SMatthew G. Knepley { 7124dde8bb0SMatthew G. Knepley DMSNES sdm; 7134e269d77SPeter Brune 7144dde8bb0SMatthew G. Knepley ierr = DMGetDMSNES(snes->dm, &sdm);CHKERRQ(ierr); 7154dde8bb0SMatthew G. Knepley if (!sdm->ops->computejacobian) { 7164dde8bb0SMatthew G. Knepley ierr = DMCopyDMSNES(dmsave, snes->dm);CHKERRQ(ierr); 7174dde8bb0SMatthew G. Knepley } 7184dde8bb0SMatthew G. Knepley } 7192b93b426SMatthew G. Knepley /* Compute the operators */ 720d1e9a80fSBarry Smith ierr = SNESComputeJacobian(snes,X,A,B);CHKERRQ(ierr); 7212b93b426SMatthew G. Knepley /* Put the previous context back */ 7228d359177SBarry Smith if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) { 7230298fd71SBarry Smith ierr = SNESSetJacobian(snes,NULL,NULL,jac,ctxsave);CHKERRQ(ierr); 7244e269d77SPeter Brune } 7254e269d77SPeter Brune 7262b93b426SMatthew G. Knepley if (Xnamed) {ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);} 727dfe15315SJed Brown snes->dm = dmsave; 728caa4e7f2SJed Brown PetscFunctionReturn(0); 729caa4e7f2SJed Brown } 730caa4e7f2SJed Brown 7316cab3a1bSJed Brown /*@ 7326cab3a1bSJed Brown SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX() 7336cab3a1bSJed Brown 7346cab3a1bSJed Brown Collective 7356cab3a1bSJed Brown 7364165533cSJose E. Roman Input Parameter: 7376cab3a1bSJed Brown . snes - snes to configure 7386cab3a1bSJed Brown 7396cab3a1bSJed Brown Level: developer 7406cab3a1bSJed Brown 7416cab3a1bSJed Brown .seealso: SNESSetUp() 7426cab3a1bSJed Brown @*/ 7436cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes) 7446cab3a1bSJed Brown { 7456cab3a1bSJed Brown PetscErrorCode ierr; 7466cab3a1bSJed Brown DM dm; 747942e3340SBarry Smith DMSNES sdm; 7486cab3a1bSJed Brown 7496cab3a1bSJed Brown PetscFunctionBegin; 7506cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 751942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 75258b371f3SBarry Smith if (!snes->jacobian && snes->mf) { 7536cab3a1bSJed Brown Mat J; 7546cab3a1bSJed Brown void *functx; 7556cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 7566cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 7576cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 7580298fd71SBarry Smith ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr); 7599e5d0892SLisandro Dalcin ierr = SNESSetJacobian(snes,J,J,NULL,NULL);CHKERRQ(ierr); 7606cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 761caa4e7f2SJed Brown } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 7626cab3a1bSJed Brown Mat J,B; 7636cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 7646cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 7656cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 766b412c318SBarry Smith ierr = DMCreateMatrix(snes->dm,&B);CHKERRQ(ierr); 76706f20277SJed Brown /* sdm->computejacobian was already set to reach here */ 7680298fd71SBarry Smith ierr = SNESSetJacobian(snes,J,B,NULL,NULL);CHKERRQ(ierr); 7696cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 7706cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 771caa4e7f2SJed Brown } else if (!snes->jacobian_pre) { 7721ba9b98eSMatthew G. Knepley PetscDS prob; 7736cab3a1bSJed Brown Mat J, B; 7741ba9b98eSMatthew G. Knepley PetscBool hasPrec = PETSC_FALSE; 7751ba9b98eSMatthew G. Knepley 7766cab3a1bSJed Brown J = snes->jacobian; 7771ba9b98eSMatthew G. Knepley ierr = DMGetDS(dm, &prob);CHKERRQ(ierr); 7781ba9b98eSMatthew G. Knepley if (prob) {ierr = PetscDSHasJacobianPreconditioner(prob, &hasPrec);CHKERRQ(ierr);} 779ec9a985fSMatthew G. Knepley if (J) {ierr = PetscObjectReference((PetscObject) J);CHKERRQ(ierr);} 780ec9a985fSMatthew G. Knepley else if (hasPrec) {ierr = DMCreateMatrix(snes->dm, &J);CHKERRQ(ierr);} 781b412c318SBarry Smith ierr = DMCreateMatrix(snes->dm, &B);CHKERRQ(ierr); 7820298fd71SBarry Smith ierr = SNESSetJacobian(snes, J ? J : B, B, NULL, NULL);CHKERRQ(ierr); 7831ba9b98eSMatthew G. Knepley ierr = MatDestroy(&J);CHKERRQ(ierr); 7846cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 7856cab3a1bSJed Brown } 786caa4e7f2SJed Brown { 787caa4e7f2SJed Brown KSP ksp; 788caa4e7f2SJed Brown ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 789caa4e7f2SJed Brown ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr); 79016ebb321SJed Brown ierr = DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 791caa4e7f2SJed Brown } 7926cab3a1bSJed Brown PetscFunctionReturn(0); 7936cab3a1bSJed Brown } 7946cab3a1bSJed Brown 795fde5950dSBarry Smith /*@C 796fde5950dSBarry Smith SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 797fde5950dSBarry Smith 798fde5950dSBarry Smith Collective on SNES 799fde5950dSBarry Smith 800fde5950dSBarry Smith Input Parameters: 801fde5950dSBarry Smith + snes - SNES object you wish to monitor 802fde5950dSBarry Smith . name - the monitor type one is seeking 803fde5950dSBarry Smith . help - message indicating what monitoring is done 804fde5950dSBarry Smith . manual - manual page for the monitor 805fde5950dSBarry Smith . monitor - the monitor function 806fde5950dSBarry Smith - monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the SNES or PetscViewer objects 807fde5950dSBarry Smith 808fde5950dSBarry Smith Level: developer 809fde5950dSBarry Smith 810fde5950dSBarry Smith .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 811fde5950dSBarry Smith PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 812fde5950dSBarry Smith PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 813fde5950dSBarry Smith PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 814fde5950dSBarry Smith PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 815fde5950dSBarry Smith PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 816fde5950dSBarry Smith PetscOptionsFList(), PetscOptionsEList() 817fde5950dSBarry Smith @*/ 818d43b4f6eSBarry Smith PetscErrorCode SNESMonitorSetFromOptions(SNES snes,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNES,PetscViewerAndFormat*)) 819fde5950dSBarry Smith { 820fde5950dSBarry Smith PetscErrorCode ierr; 821fde5950dSBarry Smith PetscViewer viewer; 822fde5950dSBarry Smith PetscViewerFormat format; 823fde5950dSBarry Smith PetscBool flg; 824fde5950dSBarry Smith 825fde5950dSBarry Smith PetscFunctionBegin; 82616413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr); 827fde5950dSBarry Smith if (flg) { 828d43b4f6eSBarry Smith PetscViewerAndFormat *vf; 829d43b4f6eSBarry Smith ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr); 830d43b4f6eSBarry Smith ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr); 831fde5950dSBarry Smith if (monitorsetup) { 832d43b4f6eSBarry Smith ierr = (*monitorsetup)(snes,vf);CHKERRQ(ierr); 833fde5950dSBarry Smith } 834d43b4f6eSBarry Smith ierr = SNESMonitorSet(snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);CHKERRQ(ierr); 835fde5950dSBarry Smith } 836fde5950dSBarry Smith PetscFunctionReturn(0); 837fde5950dSBarry Smith } 838fde5950dSBarry Smith 8399b94acceSBarry Smith /*@ 84094b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 8419b94acceSBarry Smith 842c7afd0dbSLois Curfman McInnes Collective on SNES 843c7afd0dbSLois Curfman McInnes 8449b94acceSBarry Smith Input Parameter: 8459b94acceSBarry Smith . snes - the SNES context 8469b94acceSBarry Smith 84736851e7fSLois Curfman McInnes Options Database Keys: 848722329fbSBarry Smith + -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, SNESType for complete list 84982738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 85082738288SBarry Smith of the change in the solution between steps 85170441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 852b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 853e4d06f11SPatrick Farrell . -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence 854be5caee7SBarry Smith . -snes_force_iteration <force> - force SNESSolve() to take at least one iteration 855b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 856b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 8574839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 858ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 859a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 8603d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - retains the -snes_lag_preconditioner information across multiple SNESSolve() 861e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 8623d5a8a6aSBarry Smith . -snes_lag_jacobian_persists <true,false> - retains the -snes_lag_jacobian information across multiple SNESSolve() 863b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 8642492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 86582738288SBarry Smith solver; hence iterations will continue until max_it 8661fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 86782738288SBarry Smith of convergence test 868fde5950dSBarry Smith . -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout 869fde5950dSBarry Smith . -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration 870fde5950dSBarry Smith . -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration 871fde5950dSBarry Smith . -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration 8724619e776SBarry Smith . -snes_monitor_lg_residualnorm - plots residual norm at each iteration 873459f5d12SBarry Smith . -snes_monitor_lg_range - plots residual norm at each iteration 874e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 875e2e60de9SPeter Brune . -snes_fd_color - use finite differences with coloring to compute Jacobian 8765968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 877b5badacbSBarry Smith . -snes_converged_reason - print the reason for convergence/divergence after each solve 878e62ac41dSBarry Smith . -npc_snes_type <type> - the SNES type to use as a nonlinear preconditioner 879e62ac41dSBarry Smith . -snes_test_jacobian <optional threshold> - compare the user provided Jacobian with one computed via finite differences to check for errors. If a threshold is given, display only those entries whose difference is greater than the threshold. 880e62ac41dSBarry Smith - -snes_test_jacobian_view - display the user provided Jacobian, the finite difference Jacobian and the difference between them to help users detect the location of errors in the user provided Jacobian. 88182738288SBarry Smith 88282738288SBarry Smith Options Database for Eisenstat-Walker method: 883fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 8844b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 88536851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 88636851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 88736851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 88836851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 88936851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 89036851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 89182738288SBarry Smith 89211ca99fdSLois Curfman McInnes Notes: 893ec5066bdSBarry Smith To see all options, run your program with the -help option or consult the users manual 894ec5066bdSBarry Smith 895ec5066bdSBarry Smith Notes: 896a5b23f4aSJose E. Roman SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free, and computing explicitly with 897ec5066bdSBarry Smith finite differences and coloring using MatFDColoring. It is also possible to use automatic differentiation and the MatFDColoring object. 89883e2fdc7SBarry Smith 89936851e7fSLois Curfman McInnes Level: beginner 90036851e7fSLois Curfman McInnes 901ec5066bdSBarry Smith .seealso: SNESSetOptionsPrefix(), SNESResetFromOptions(), SNES, SNESCreate() 9029b94acceSBarry Smith @*/ 9037087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 9049b94acceSBarry Smith { 9058afaa268SBarry Smith PetscBool flg,pcset,persist,set; 906d8f46077SPeter Brune PetscInt i,indx,lag,grids; 90704d7464bSBarry Smith const char *deft = SNESNEWTONLS; 908649ef022SMatthew Knepley const char *convtests[] = {"default","skip","correct_pressure"}; 90985385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 910e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 91185385478SLisandro Dalcin PetscErrorCode ierr; 912c40d0f55SPeter Brune PCSide pcside; 913a64e098fSPeter Brune const char *optionsprefix; 9149b94acceSBarry Smith 9153a40ed3dSBarry Smith PetscFunctionBegin; 9160700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9170f51fdf8SToby Isaac ierr = SNESRegisterAll();CHKERRQ(ierr); 9183194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 919639ff905SBarry Smith if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name; 920a264d7a6SBarry Smith ierr = PetscOptionsFList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 921d64ed03dSBarry Smith if (flg) { 922186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 9237adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 924186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 925d64ed03dSBarry Smith } 92694ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,NULL);CHKERRQ(ierr); 92794ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,NULL);CHKERRQ(ierr); 928186905e3SBarry Smith 92994ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,NULL);CHKERRQ(ierr); 930e4d06f11SPatrick Farrell ierr = PetscOptionsReal("-snes_divergence_tolerance","Stop if residual norm increases by this factor","SNESSetDivergenceTolerance",snes->divtol,&snes->divtol,NULL);CHKERRQ(ierr); 9310298fd71SBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,NULL);CHKERRQ(ierr); 9320298fd71SBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,NULL);CHKERRQ(ierr); 9330298fd71SBarry Smith ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,NULL);CHKERRQ(ierr); 9340298fd71SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,NULL);CHKERRQ(ierr); 9350298fd71SBarry Smith ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,NULL);CHKERRQ(ierr); 9360d6f27a8SBarry Smith ierr = PetscOptionsBool("-snes_force_iteration","Force SNESSolve() to take at least one iteration","SNESSetForceIteration",snes->forceiteration,&snes->forceiteration,NULL);CHKERRQ(ierr); 937b351a90bSFande Kong ierr = PetscOptionsBool("-snes_check_jacobian_domain_error","Check Jacobian domain error after Jacobian evaluation","SNESCheckJacobianDomainError",snes->checkjacdomainerror,&snes->checkjacdomainerror,NULL);CHKERRQ(ierr); 93885385478SLisandro Dalcin 939a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 940a8054027SBarry Smith if (flg) { 9413d5a8a6aSBarry Smith if (lag == -1) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Cannot set the lag to -1 from the command line since the preconditioner must be built as least once, perhaps you mean -2"); 942a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 943a8054027SBarry Smith } 9449590daa0SBarry Smith ierr = PetscOptionsBool("-snes_lag_preconditioner_persists","Preconditioner lagging through multiple SNES solves","SNESSetLagPreconditionerPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr); 94537ec4e1aSPeter Brune if (flg) { 94637ec4e1aSPeter Brune ierr = SNESSetLagPreconditionerPersists(snes,persist);CHKERRQ(ierr); 94737ec4e1aSPeter Brune } 948e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 949e35cf81dSBarry Smith if (flg) { 9503d5a8a6aSBarry Smith if (lag == -1) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Cannot set the lag to -1 from the command line since the Jacobian must be built as least once, perhaps you mean -2"); 951e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 952e35cf81dSBarry Smith } 9539590daa0SBarry Smith ierr = PetscOptionsBool("-snes_lag_jacobian_persists","Jacobian lagging through multiple SNES solves","SNESSetLagJacobianPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr); 95437ec4e1aSPeter Brune if (flg) { 95537ec4e1aSPeter Brune ierr = SNESSetLagJacobianPersists(snes,persist);CHKERRQ(ierr); 95637ec4e1aSPeter Brune } 95737ec4e1aSPeter Brune 958efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 959efd51863SBarry Smith if (flg) { 960efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 961efd51863SBarry Smith } 962a8054027SBarry Smith 963649ef022SMatthew Knepley ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,sizeof(convtests)/sizeof(char*),"default",&indx,&flg);CHKERRQ(ierr); 96485385478SLisandro Dalcin if (flg) { 96585385478SLisandro Dalcin switch (indx) { 9668d359177SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESConvergedDefault,NULL,NULL);CHKERRQ(ierr); break; 967e2a6519dSDmitry Karpeev case 1: ierr = SNESSetConvergenceTest(snes,SNESConvergedSkip,NULL,NULL);CHKERRQ(ierr); break; 968649ef022SMatthew Knepley case 2: ierr = SNESSetConvergenceTest(snes,SNESConvergedCorrectPressure,NULL,NULL);CHKERRQ(ierr); break; 96985385478SLisandro Dalcin } 97085385478SLisandro Dalcin } 97185385478SLisandro Dalcin 972365a6726SPeter Brune ierr = PetscOptionsEList("-snes_norm_schedule","SNES Norm schedule","SNESSetNormSchedule",SNESNormSchedules,5,"function",&indx,&flg);CHKERRQ(ierr); 973365a6726SPeter Brune if (flg) { ierr = SNESSetNormSchedule(snes,(SNESNormSchedule)indx);CHKERRQ(ierr); } 974fdacfa88SPeter Brune 97547073ea2SPeter Brune ierr = PetscOptionsEList("-snes_function_type","SNES Norm schedule","SNESSetFunctionType",SNESFunctionTypes,2,"unpreconditioned",&indx,&flg);CHKERRQ(ierr); 97647073ea2SPeter Brune if (flg) { ierr = SNESSetFunctionType(snes,(SNESFunctionType)indx);CHKERRQ(ierr); } 977186905e3SBarry Smith 97885385478SLisandro Dalcin kctx = (SNESKSPEW*)snes->kspconvctx; 97985385478SLisandro Dalcin 9800298fd71SBarry Smith ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,NULL);CHKERRQ(ierr); 981186905e3SBarry Smith 98294ae4db5SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,NULL);CHKERRQ(ierr); 98394ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,NULL);CHKERRQ(ierr); 98494ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,NULL);CHKERRQ(ierr); 98594ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,NULL);CHKERRQ(ierr); 98694ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,NULL);CHKERRQ(ierr); 98794ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,NULL);CHKERRQ(ierr); 98894ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,NULL);CHKERRQ(ierr); 989186905e3SBarry Smith 99090d69ab7SBarry Smith flg = PETSC_FALSE; 9918afaa268SBarry Smith ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,&set);CHKERRQ(ierr); 9928afaa268SBarry Smith if (set && flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 993eabae89aSBarry Smith 994*fbcc4530SMatthew G. Knepley ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor","Monitor norm of function","SNESMonitorDefault",SNESMonitorDefault,SNESMonitorDefaultSetUp);CHKERRQ(ierr); 995fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_short","Monitor norm of function with fewer digits","SNESMonitorDefaultShort",SNESMonitorDefaultShort,NULL);CHKERRQ(ierr); 996fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_range","Monitor range of elements of function","SNESMonitorRange",SNESMonitorRange,NULL);CHKERRQ(ierr); 997eabae89aSBarry Smith 998fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_ratio","Monitor ratios of the norm of function for consecutive steps","SNESMonitorRatio",SNESMonitorRatio,SNESMonitorRatioSetUp);CHKERRQ(ierr); 999fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_field","Monitor norm of function (split into fields)","SNESMonitorDefaultField",SNESMonitorDefaultField,NULL);CHKERRQ(ierr); 1000fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_solution","View solution at each iteration","SNESMonitorSolution",SNESMonitorSolution,NULL);CHKERRQ(ierr); 1001fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_solution_update","View correction at each iteration","SNESMonitorSolutionUpdate",SNESMonitorSolutionUpdate,NULL);CHKERRQ(ierr); 1002fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_residual","View residual at each iteration","SNESMonitorResidual",SNESMonitorResidual,NULL);CHKERRQ(ierr); 1003fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",SNESMonitorJacUpdateSpectrum,NULL);CHKERRQ(ierr); 1004fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_fields","Monitor norm of function per field","SNESMonitorSet",SNESMonitorFields,NULL);CHKERRQ(ierr); 10052db13446SMatthew G. Knepley 1006589a23caSBarry Smith ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",NULL,monfilename,sizeof(monfilename),&flg);CHKERRQ(ierr); 10075180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 10085180491cSLisandro Dalcin 100990d69ab7SBarry Smith flg = PETSC_FALSE; 10100298fd71SBarry Smith ierr = PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,NULL);CHKERRQ(ierr); 1011459f5d12SBarry Smith if (flg) { 1012459f5d12SBarry Smith PetscViewer ctx; 1013e24b481bSBarry Smith 10146ba87a44SLisandro Dalcin ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr); 1015459f5d12SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 1016459f5d12SBarry Smith } 10172e7541e6SPeter Brune 101890d69ab7SBarry Smith flg = PETSC_FALSE; 1019c4421ceaSFande Kong ierr = PetscOptionsBool("-snes_converged_reason_view_cancel","Remove all converged reason viewers","SNESConvergedReasonViewCancel",flg,&flg,&set);CHKERRQ(ierr); 1020c4421ceaSFande Kong if (set && flg) {ierr = SNESConvergedReasonViewCancel(snes);CHKERRQ(ierr);} 1021c4421ceaSFande Kong 1022c4421ceaSFande Kong flg = PETSC_FALSE; 10238d359177SBarry Smith ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESComputeJacobianDefault",flg,&flg,NULL);CHKERRQ(ierr); 10244b27c08aSLois Curfman McInnes if (flg) { 10256cab3a1bSJed Brown void *functx; 1026b1f624c7SBarry Smith DM dm; 1027b1f624c7SBarry Smith DMSNES sdm; 1028b1f624c7SBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1029b1f624c7SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 1030b1f624c7SBarry Smith sdm->jacobianctx = NULL; 10310298fd71SBarry Smith ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr); 10328d359177SBarry Smith ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefault,functx);CHKERRQ(ierr); 1033ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 10349b94acceSBarry Smith } 1035639f9d9dSBarry Smith 103644848bc4SPeter Brune flg = PETSC_FALSE; 10378d359177SBarry Smith ierr = PetscOptionsBool("-snes_fd_function","Use finite differences (slow) to compute function from user objective","SNESObjectiveComputeFunctionDefaultFD",flg,&flg,NULL);CHKERRQ(ierr); 103897584545SPeter Brune if (flg) { 10398d359177SBarry Smith ierr = SNESSetFunction(snes,NULL,SNESObjectiveComputeFunctionDefaultFD,NULL);CHKERRQ(ierr); 104097584545SPeter Brune } 104197584545SPeter Brune 104297584545SPeter Brune flg = PETSC_FALSE; 10438d359177SBarry Smith ierr = PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESComputeJacobianDefaultColor",flg,&flg,NULL);CHKERRQ(ierr); 104444848bc4SPeter Brune if (flg) { 1045c52e227fSPeter Brune DM dm; 1046c52e227fSPeter Brune DMSNES sdm; 1047c52e227fSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1048aace71b7SPeter Brune ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 1049aace71b7SPeter Brune sdm->jacobianctx = NULL; 10509e5d0892SLisandro Dalcin ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr); 105144848bc4SPeter Brune ierr = PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr); 105244848bc4SPeter Brune } 105344848bc4SPeter Brune 1054aa3661deSLisandro Dalcin flg = PETSC_FALSE; 1055f871313dSBarry Smith ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf_operator,&flg);CHKERRQ(ierr); 1056d8f46077SPeter Brune if (flg && snes->mf_operator) { 1057a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 1058d8f46077SPeter Brune snes->mf = PETSC_TRUE; 1059a8248277SBarry Smith } 1060aa3661deSLisandro Dalcin flg = PETSC_FALSE; 1061f871313dSBarry Smith ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf,&flg);CHKERRQ(ierr); 1062d8f46077SPeter Brune if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE; 10639e5d0892SLisandro Dalcin ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,NULL);CHKERRQ(ierr); 1064d28543b3SPeter Brune 1065c40d0f55SPeter Brune flg = PETSC_FALSE; 1066be95d8f1SBarry Smith ierr = SNESGetNPCSide(snes,&pcside);CHKERRQ(ierr); 1067be95d8f1SBarry Smith ierr = PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetNPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);CHKERRQ(ierr); 1068be95d8f1SBarry Smith if (flg) {ierr = SNESSetNPCSide(snes,pcside);CHKERRQ(ierr);} 1069c40d0f55SPeter Brune 1070e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 10718a70d858SHong Zhang /* 10728a70d858SHong Zhang Publish convergence information using SAWs 10738a70d858SHong Zhang */ 10748a70d858SHong Zhang flg = PETSC_FALSE; 10758a70d858SHong Zhang ierr = PetscOptionsBool("-snes_monitor_saws","Publish SNES progress using SAWs","SNESMonitorSet",flg,&flg,NULL);CHKERRQ(ierr); 10768a70d858SHong Zhang if (flg) { 10778a70d858SHong Zhang void *ctx; 10788a70d858SHong Zhang ierr = SNESMonitorSAWsCreate(snes,&ctx);CHKERRQ(ierr); 10798a70d858SHong Zhang ierr = SNESMonitorSet(snes,SNESMonitorSAWs,ctx,SNESMonitorSAWsDestroy);CHKERRQ(ierr); 10808a70d858SHong Zhang } 10818a70d858SHong Zhang #endif 10828a70d858SHong Zhang #if defined(PETSC_HAVE_SAWS) 1083b90c6cbeSBarry Smith { 1084b90c6cbeSBarry Smith PetscBool set; 1085b90c6cbeSBarry Smith flg = PETSC_FALSE; 10868a70d858SHong Zhang ierr = PetscOptionsBool("-snes_saws_block","Block for SAWs at end of SNESSolve","PetscObjectSAWsBlock",((PetscObject)snes)->amspublishblock,&flg,&set);CHKERRQ(ierr); 1087b90c6cbeSBarry Smith if (set) { 1088e04113cfSBarry Smith ierr = PetscObjectSAWsSetBlock((PetscObject)snes,flg);CHKERRQ(ierr); 1089b90c6cbeSBarry Smith } 1090b90c6cbeSBarry Smith } 1091b90c6cbeSBarry Smith #endif 1092b90c6cbeSBarry Smith 109376b2cf59SMatthew Knepley for (i = 0; i < numberofsetfromoptions; i++) { 109476b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 109576b2cf59SMatthew Knepley } 109676b2cf59SMatthew Knepley 1097e7788613SBarry Smith if (snes->ops->setfromoptions) { 1098e55864a3SBarry Smith ierr = (*snes->ops->setfromoptions)(PetscOptionsObject,snes);CHKERRQ(ierr); 1099639f9d9dSBarry Smith } 11005d973c19SBarry Smith 11015d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 11020633abcbSJed Brown ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)snes);CHKERRQ(ierr); 1103b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 11044bbc92c1SBarry Smith 1105d8d34be6SBarry Smith if (snes->linesearch) { 11067601faf0SJed Brown ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 1107f1c6b773SPeter Brune ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr); 1108d8d34be6SBarry Smith } 11099e764e56SPeter Brune 11106aa5e7e9SBarry Smith if (snes->usesksp) { 11116991f827SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 11126991f827SBarry Smith ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre);CHKERRQ(ierr); 11136991f827SBarry Smith ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 11146aa5e7e9SBarry Smith } 11156991f827SBarry Smith 1116b5badacbSBarry Smith /* if user has set the SNES NPC type via options database, create it. */ 111751e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 1118c5929fdfSBarry Smith ierr = PetscOptionsHasName(((PetscObject)snes)->options,optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 1119efd4aadfSBarry Smith if (pcset && (!snes->npc)) { 1120efd4aadfSBarry Smith ierr = SNESGetNPC(snes, &snes->npc);CHKERRQ(ierr); 112151e86f29SPeter Brune } 1122b5badacbSBarry Smith if (snes->npc) { 1123b5badacbSBarry Smith ierr = SNESSetFromOptions(snes->npc);CHKERRQ(ierr); 1124b5badacbSBarry Smith } 1125b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled++; 1126b3cd9a81SMatthew G. Knepley PetscFunctionReturn(0); 1127b3cd9a81SMatthew G. Knepley } 1128b3cd9a81SMatthew G. Knepley 1129b3cd9a81SMatthew G. Knepley /*@ 1130b3cd9a81SMatthew G. Knepley SNESResetFromOptions - Sets various SNES and KSP parameters from user options ONLY if the SNES was previously set from options 1131b3cd9a81SMatthew G. Knepley 1132b3cd9a81SMatthew G. Knepley Collective on SNES 1133b3cd9a81SMatthew G. Knepley 1134b3cd9a81SMatthew G. Knepley Input Parameter: 1135b3cd9a81SMatthew G. Knepley . snes - the SNES context 1136b3cd9a81SMatthew G. Knepley 1137b3cd9a81SMatthew G. Knepley Level: beginner 1138b3cd9a81SMatthew G. Knepley 1139b3cd9a81SMatthew G. Knepley .seealso: SNESSetFromOptions(), SNESSetOptionsPrefix() 1140b3cd9a81SMatthew G. Knepley @*/ 1141b3cd9a81SMatthew G. Knepley PetscErrorCode SNESResetFromOptions(SNES snes) 1142b3cd9a81SMatthew G. Knepley { 1143b3cd9a81SMatthew G. Knepley PetscErrorCode ierr; 1144b3cd9a81SMatthew G. Knepley 1145b3cd9a81SMatthew G. Knepley PetscFunctionBegin; 1146b3cd9a81SMatthew G. Knepley if (snes->setfromoptionscalled) {ierr = SNESSetFromOptions(snes);CHKERRQ(ierr);} 11473a40ed3dSBarry Smith PetscFunctionReturn(0); 11489b94acceSBarry Smith } 11499b94acceSBarry Smith 1150bb9467b5SJed Brown /*@C 1151d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 1152d25893d9SBarry Smith the nonlinear solvers. 1153d25893d9SBarry Smith 1154d25893d9SBarry Smith Logically Collective on SNES 1155d25893d9SBarry Smith 1156d25893d9SBarry Smith Input Parameters: 1157d25893d9SBarry Smith + snes - the SNES context 1158d25893d9SBarry Smith . compute - function to compute the context 1159d25893d9SBarry Smith - destroy - function to destroy the context 1160d25893d9SBarry Smith 1161d25893d9SBarry Smith Level: intermediate 1162d25893d9SBarry Smith 1163bb9467b5SJed Brown Notes: 1164bb9467b5SJed Brown This function is currently not available from Fortran. 1165bb9467b5SJed Brown 1166d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 1167d25893d9SBarry Smith @*/ 1168d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 1169d25893d9SBarry Smith { 1170d25893d9SBarry Smith PetscFunctionBegin; 1171d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1172d25893d9SBarry Smith snes->ops->usercompute = compute; 1173d25893d9SBarry Smith snes->ops->userdestroy = destroy; 1174d25893d9SBarry Smith PetscFunctionReturn(0); 1175d25893d9SBarry Smith } 1176a847f771SSatish Balay 1177b07ff414SBarry Smith /*@ 11789b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 11799b94acceSBarry Smith the nonlinear solvers. 11809b94acceSBarry Smith 11813f9fe445SBarry Smith Logically Collective on SNES 1182fee21e36SBarry Smith 1183c7afd0dbSLois Curfman McInnes Input Parameters: 1184c7afd0dbSLois Curfman McInnes + snes - the SNES context 1185c7afd0dbSLois Curfman McInnes - usrP - optional user context 1186c7afd0dbSLois Curfman McInnes 118736851e7fSLois Curfman McInnes Level: intermediate 118836851e7fSLois Curfman McInnes 118995452b02SPatrick Sanan Fortran Notes: 119095452b02SPatrick Sanan To use this from Fortran you must write a Fortran interface definition for this 1191daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1192daf670e6SBarry Smith 1193ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext() 11949b94acceSBarry Smith @*/ 11957087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 11969b94acceSBarry Smith { 11971b2093e4SBarry Smith PetscErrorCode ierr; 1198b07ff414SBarry Smith KSP ksp; 11991b2093e4SBarry Smith 12003a40ed3dSBarry Smith PetscFunctionBegin; 12010700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1202b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 1203b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 12049b94acceSBarry Smith snes->user = usrP; 12053a40ed3dSBarry Smith PetscFunctionReturn(0); 12069b94acceSBarry Smith } 120774679c65SBarry Smith 1208b07ff414SBarry Smith /*@ 12099b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 12109b94acceSBarry Smith nonlinear solvers. 12119b94acceSBarry Smith 1212c7afd0dbSLois Curfman McInnes Not Collective 1213c7afd0dbSLois Curfman McInnes 12149b94acceSBarry Smith Input Parameter: 12159b94acceSBarry Smith . snes - SNES context 12169b94acceSBarry Smith 12179b94acceSBarry Smith Output Parameter: 12189b94acceSBarry Smith . usrP - user context 12199b94acceSBarry Smith 122095452b02SPatrick Sanan Fortran Notes: 122195452b02SPatrick Sanan To use this from Fortran you must write a Fortran interface definition for this 1222daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1223daf670e6SBarry Smith 122436851e7fSLois Curfman McInnes Level: intermediate 122536851e7fSLois Curfman McInnes 12269b94acceSBarry Smith .seealso: SNESSetApplicationContext() 12279b94acceSBarry Smith @*/ 1228e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 12299b94acceSBarry Smith { 12303a40ed3dSBarry Smith PetscFunctionBegin; 12310700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1232e71120c6SJed Brown *(void**)usrP = snes->user; 12333a40ed3dSBarry Smith PetscFunctionReturn(0); 12349b94acceSBarry Smith } 123574679c65SBarry Smith 12369b94acceSBarry Smith /*@ 1237ec5066bdSBarry Smith SNESSetUseMatrixFree - indicates that SNES should use matrix free finite difference matrix vector products internally to apply the Jacobian. 12383565c898SBarry Smith 12393565c898SBarry Smith Collective on SNES 12403565c898SBarry Smith 12413565c898SBarry Smith Input Parameters: 12423565c898SBarry Smith + snes - SNES context 12434ddffce6SLisandro Dalcin . mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used 12444ddffce6SLisandro Dalcin - mf - use matrix-free for both the Amat and Pmat used by SNESSetJacobian(), both the Amat and Pmat set in SNESSetJacobian() will be ignored 12453565c898SBarry Smith 12463565c898SBarry Smith Options Database: 12473565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator 1248ec5066bdSBarry Smith . -snes_mf_operator - use matrix free only for the mat operator 1249ec5066bdSBarry Smith . -snes_fd_color - compute the Jacobian via coloring and finite differences. 1250ec5066bdSBarry Smith - -snes_fd - compute the Jacobian via finite differences (slow) 12513565c898SBarry Smith 12523565c898SBarry Smith Level: intermediate 12533565c898SBarry Smith 1254ec5066bdSBarry Smith Notes: 1255a5b23f4aSJose E. Roman SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free, and computing explicitly with 1256ec5066bdSBarry Smith finite differences and coloring using MatFDColoring. It is also possible to use automatic differentiation and the MatFDColoring object. 1257ec5066bdSBarry Smith 1258ec5066bdSBarry Smith .seealso: SNESGetUseMatrixFree(), MatCreateSNESMF(), SNESComputeJacobianDefaultColor() 12593565c898SBarry Smith @*/ 12603565c898SBarry Smith PetscErrorCode SNESSetUseMatrixFree(SNES snes,PetscBool mf_operator,PetscBool mf) 12613565c898SBarry Smith { 12623565c898SBarry Smith PetscFunctionBegin; 12633565c898SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 126488b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes,mf_operator,2); 126588b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes,mf,3); 12664ddffce6SLisandro Dalcin snes->mf = mf_operator ? PETSC_TRUE : mf; 12673565c898SBarry Smith snes->mf_operator = mf_operator; 12683565c898SBarry Smith PetscFunctionReturn(0); 12693565c898SBarry Smith } 12703565c898SBarry Smith 12713565c898SBarry Smith /*@ 1272ec5066bdSBarry Smith SNESGetUseMatrixFree - indicates if the SNES uses matrix free finite difference matrix vector products to apply the Jacobian. 12733565c898SBarry Smith 12743565c898SBarry Smith Collective on SNES 12753565c898SBarry Smith 12763565c898SBarry Smith Input Parameter: 12773565c898SBarry Smith . snes - SNES context 12783565c898SBarry Smith 12793565c898SBarry Smith Output Parameters: 12804ddffce6SLisandro Dalcin + mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used 12814ddffce6SLisandro Dalcin - mf - use matrix-free for both the Amat and Pmat used by SNESSetJacobian(), both the Amat and Pmat set in SNESSetJacobian() will be ignored 12823565c898SBarry Smith 12833565c898SBarry Smith Options Database: 12843565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator 12853565c898SBarry Smith - -snes_mf_operator - use matrix free only for the mat operator 12863565c898SBarry Smith 12873565c898SBarry Smith Level: intermediate 12883565c898SBarry Smith 12893565c898SBarry Smith .seealso: SNESSetUseMatrixFree(), MatCreateSNESMF() 12903565c898SBarry Smith @*/ 12913565c898SBarry Smith PetscErrorCode SNESGetUseMatrixFree(SNES snes,PetscBool *mf_operator,PetscBool *mf) 12923565c898SBarry Smith { 12933565c898SBarry Smith PetscFunctionBegin; 12943565c898SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12953565c898SBarry Smith if (mf) *mf = snes->mf; 12963565c898SBarry Smith if (mf_operator) *mf_operator = snes->mf_operator; 12973565c898SBarry Smith PetscFunctionReturn(0); 12983565c898SBarry Smith } 12993565c898SBarry Smith 13003565c898SBarry Smith /*@ 1301c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 1302c8228a4eSBarry Smith at this time. 13039b94acceSBarry Smith 1304c7afd0dbSLois Curfman McInnes Not Collective 1305c7afd0dbSLois Curfman McInnes 13069b94acceSBarry Smith Input Parameter: 13079b94acceSBarry Smith . snes - SNES context 13089b94acceSBarry Smith 13099b94acceSBarry Smith Output Parameter: 13109b94acceSBarry Smith . iter - iteration number 13119b94acceSBarry Smith 1312c8228a4eSBarry Smith Notes: 1313c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 1314c8228a4eSBarry Smith 1315c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 131608405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 131708405cd6SLois Curfman McInnes .vb 131808405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 131908405cd6SLois Curfman McInnes if (!(it % 2)) { 132008405cd6SLois Curfman McInnes [compute Jacobian here] 132108405cd6SLois Curfman McInnes } 132208405cd6SLois Curfman McInnes .ve 1323c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 132408405cd6SLois Curfman McInnes recomputed every second SNES iteration. 1325c8228a4eSBarry Smith 1326c04deec6SBarry Smith After the SNES solve is complete this will return the number of nonlinear iterations used. 1327c04deec6SBarry Smith 132836851e7fSLois Curfman McInnes Level: intermediate 132936851e7fSLois Curfman McInnes 133071dbe336SPeter Brune .seealso: SNESGetLinearSolveIterations() 13319b94acceSBarry Smith @*/ 13327087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt *iter) 13339b94acceSBarry Smith { 13343a40ed3dSBarry Smith PetscFunctionBegin; 13350700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13364482741eSBarry Smith PetscValidIntPointer(iter,2); 13379b94acceSBarry Smith *iter = snes->iter; 13383a40ed3dSBarry Smith PetscFunctionReturn(0); 13399b94acceSBarry Smith } 134074679c65SBarry Smith 1341360c497dSPeter Brune /*@ 1342360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 1343360c497dSPeter Brune 1344360c497dSPeter Brune Not Collective 1345360c497dSPeter Brune 1346d8d19677SJose E. Roman Input Parameters: 1347a2b725a8SWilliam Gropp + snes - SNES context 1348a2b725a8SWilliam Gropp - iter - iteration number 1349360c497dSPeter Brune 1350360c497dSPeter Brune Level: developer 1351360c497dSPeter Brune 135271dbe336SPeter Brune .seealso: SNESGetLinearSolveIterations() 1353360c497dSPeter Brune @*/ 1354360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 1355360c497dSPeter Brune { 1356360c497dSPeter Brune PetscErrorCode ierr; 1357360c497dSPeter Brune 1358360c497dSPeter Brune PetscFunctionBegin; 1359360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1360e04113cfSBarry Smith ierr = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr); 1361360c497dSPeter Brune snes->iter = iter; 1362e04113cfSBarry Smith ierr = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr); 1363360c497dSPeter Brune PetscFunctionReturn(0); 1364360c497dSPeter Brune } 1365360c497dSPeter Brune 13669b94acceSBarry Smith /*@ 1367b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 13689b94acceSBarry Smith attempted by the nonlinear solver. 13699b94acceSBarry Smith 1370c7afd0dbSLois Curfman McInnes Not Collective 1371c7afd0dbSLois Curfman McInnes 13729b94acceSBarry Smith Input Parameter: 13739b94acceSBarry Smith . snes - SNES context 13749b94acceSBarry Smith 13759b94acceSBarry Smith Output Parameter: 13769b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 13779b94acceSBarry Smith 1378c96a6f78SLois Curfman McInnes Notes: 1379c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1380c96a6f78SLois Curfman McInnes 138136851e7fSLois Curfman McInnes Level: intermediate 138236851e7fSLois Curfman McInnes 1383e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 138458ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 13859b94acceSBarry Smith @*/ 13867087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt *nfails) 13879b94acceSBarry Smith { 13883a40ed3dSBarry Smith PetscFunctionBegin; 13890700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13904482741eSBarry Smith PetscValidIntPointer(nfails,2); 139150ffb88aSMatthew Knepley *nfails = snes->numFailures; 139250ffb88aSMatthew Knepley PetscFunctionReturn(0); 139350ffb88aSMatthew Knepley } 139450ffb88aSMatthew Knepley 139550ffb88aSMatthew Knepley /*@ 1396b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 139750ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 139850ffb88aSMatthew Knepley 139950ffb88aSMatthew Knepley Not Collective 140050ffb88aSMatthew Knepley 140150ffb88aSMatthew Knepley Input Parameters: 140250ffb88aSMatthew Knepley + snes - SNES context 140350ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 140450ffb88aSMatthew Knepley 140550ffb88aSMatthew Knepley Level: intermediate 140650ffb88aSMatthew Knepley 1407e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 140858ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 140950ffb88aSMatthew Knepley @*/ 14107087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 141150ffb88aSMatthew Knepley { 141250ffb88aSMatthew Knepley PetscFunctionBegin; 14130700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 141450ffb88aSMatthew Knepley snes->maxFailures = maxFails; 141550ffb88aSMatthew Knepley PetscFunctionReturn(0); 141650ffb88aSMatthew Knepley } 141750ffb88aSMatthew Knepley 141850ffb88aSMatthew Knepley /*@ 1419b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 142050ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 142150ffb88aSMatthew Knepley 142250ffb88aSMatthew Knepley Not Collective 142350ffb88aSMatthew Knepley 142450ffb88aSMatthew Knepley Input Parameter: 142550ffb88aSMatthew Knepley . snes - SNES context 142650ffb88aSMatthew Knepley 142750ffb88aSMatthew Knepley Output Parameter: 142850ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 142950ffb88aSMatthew Knepley 143050ffb88aSMatthew Knepley Level: intermediate 143150ffb88aSMatthew Knepley 1432e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 143358ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 143458ebbce7SBarry Smith 143550ffb88aSMatthew Knepley @*/ 14367087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 143750ffb88aSMatthew Knepley { 143850ffb88aSMatthew Knepley PetscFunctionBegin; 14390700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14404482741eSBarry Smith PetscValidIntPointer(maxFails,2); 144150ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 14423a40ed3dSBarry Smith PetscFunctionReturn(0); 14439b94acceSBarry Smith } 1444a847f771SSatish Balay 14452541af92SBarry Smith /*@ 14462541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 14472541af92SBarry Smith done by SNES. 14482541af92SBarry Smith 14492541af92SBarry Smith Not Collective 14502541af92SBarry Smith 14512541af92SBarry Smith Input Parameter: 14522541af92SBarry Smith . snes - SNES context 14532541af92SBarry Smith 14542541af92SBarry Smith Output Parameter: 14552541af92SBarry Smith . nfuncs - number of evaluations 14562541af92SBarry Smith 14572541af92SBarry Smith Level: intermediate 14582541af92SBarry Smith 145995452b02SPatrick Sanan Notes: 146095452b02SPatrick Sanan Reset every time SNESSolve is called unless SNESSetCountersReset() is used. 1461971e163fSPeter Brune 1462971e163fSPeter Brune .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), SNESSetCountersReset() 14632541af92SBarry Smith @*/ 14647087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 14652541af92SBarry Smith { 14662541af92SBarry Smith PetscFunctionBegin; 14670700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14682541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 14692541af92SBarry Smith *nfuncs = snes->nfuncs; 14702541af92SBarry Smith PetscFunctionReturn(0); 14712541af92SBarry Smith } 14722541af92SBarry Smith 14733d4c4710SBarry Smith /*@ 14743d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 14753d4c4710SBarry Smith linear solvers. 14763d4c4710SBarry Smith 14773d4c4710SBarry Smith Not Collective 14783d4c4710SBarry Smith 14793d4c4710SBarry Smith Input Parameter: 14803d4c4710SBarry Smith . snes - SNES context 14813d4c4710SBarry Smith 14823d4c4710SBarry Smith Output Parameter: 14833d4c4710SBarry Smith . nfails - number of failed solves 14843d4c4710SBarry Smith 14859d85da0cSMatthew G. Knepley Level: intermediate 14869d85da0cSMatthew G. Knepley 14879d85da0cSMatthew G. Knepley Options Database Keys: 14889d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 14899d85da0cSMatthew G. Knepley 14903d4c4710SBarry Smith Notes: 14913d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 14923d4c4710SBarry Smith 1493e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 14943d4c4710SBarry Smith @*/ 14957087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt *nfails) 14963d4c4710SBarry Smith { 14973d4c4710SBarry Smith PetscFunctionBegin; 14980700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14993d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 15003d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 15013d4c4710SBarry Smith PetscFunctionReturn(0); 15023d4c4710SBarry Smith } 15033d4c4710SBarry Smith 15043d4c4710SBarry Smith /*@ 15053d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 15063d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 15073d4c4710SBarry Smith 15083f9fe445SBarry Smith Logically Collective on SNES 15093d4c4710SBarry Smith 15103d4c4710SBarry Smith Input Parameters: 15113d4c4710SBarry Smith + snes - SNES context 15123d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 15133d4c4710SBarry Smith 15143d4c4710SBarry Smith Level: intermediate 15153d4c4710SBarry Smith 15169d85da0cSMatthew G. Knepley Options Database Keys: 15179d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 15189d85da0cSMatthew G. Knepley 151995452b02SPatrick Sanan Notes: 152095452b02SPatrick Sanan By default this is 0; that is SNES returns on the first failed linear solve 15213d4c4710SBarry Smith 152258ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 15233d4c4710SBarry Smith @*/ 15247087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 15253d4c4710SBarry Smith { 15263d4c4710SBarry Smith PetscFunctionBegin; 15270700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1528c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 15293d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 15303d4c4710SBarry Smith PetscFunctionReturn(0); 15313d4c4710SBarry Smith } 15323d4c4710SBarry Smith 15333d4c4710SBarry Smith /*@ 15343d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 15353d4c4710SBarry Smith are allowed before SNES terminates 15363d4c4710SBarry Smith 15373d4c4710SBarry Smith Not Collective 15383d4c4710SBarry Smith 15393d4c4710SBarry Smith Input Parameter: 15403d4c4710SBarry Smith . snes - SNES context 15413d4c4710SBarry Smith 15423d4c4710SBarry Smith Output Parameter: 15433d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 15443d4c4710SBarry Smith 15453d4c4710SBarry Smith Level: intermediate 15463d4c4710SBarry Smith 154795452b02SPatrick Sanan Notes: 154895452b02SPatrick Sanan By default this is 1; that is SNES returns on the first failed linear solve 15493d4c4710SBarry Smith 1550e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 15513d4c4710SBarry Smith @*/ 15527087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 15533d4c4710SBarry Smith { 15543d4c4710SBarry Smith PetscFunctionBegin; 15550700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15563d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 15573d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 15583d4c4710SBarry Smith PetscFunctionReturn(0); 15593d4c4710SBarry Smith } 15603d4c4710SBarry Smith 1561c96a6f78SLois Curfman McInnes /*@ 1562b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1563c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1564c96a6f78SLois Curfman McInnes 1565c7afd0dbSLois Curfman McInnes Not Collective 1566c7afd0dbSLois Curfman McInnes 1567c96a6f78SLois Curfman McInnes Input Parameter: 1568c96a6f78SLois Curfman McInnes . snes - SNES context 1569c96a6f78SLois Curfman McInnes 1570c96a6f78SLois Curfman McInnes Output Parameter: 1571c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1572c96a6f78SLois Curfman McInnes 1573c96a6f78SLois Curfman McInnes Notes: 1574971e163fSPeter Brune This counter is reset to zero for each successive call to SNESSolve() unless SNESSetCountersReset() is used. 1575c96a6f78SLois Curfman McInnes 1576010be392SBarry Smith If the linear solver fails inside the SNESSolve() the iterations for that call to the linear solver are not included. If you wish to count them 1577010be392SBarry Smith then call KSPGetIterationNumber() after the failed solve. 1578010be392SBarry Smith 157936851e7fSLois Curfman McInnes Level: intermediate 158036851e7fSLois Curfman McInnes 158171dbe336SPeter Brune .seealso: SNESGetIterationNumber(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESSetCountersReset() 1582c96a6f78SLois Curfman McInnes @*/ 15837087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt *lits) 1584c96a6f78SLois Curfman McInnes { 15853a40ed3dSBarry Smith PetscFunctionBegin; 15860700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15874482741eSBarry Smith PetscValidIntPointer(lits,2); 1588c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 15893a40ed3dSBarry Smith PetscFunctionReturn(0); 1590c96a6f78SLois Curfman McInnes } 1591c96a6f78SLois Curfman McInnes 1592971e163fSPeter Brune /*@ 1593971e163fSPeter Brune SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations 1594971e163fSPeter Brune are reset every time SNESSolve() is called. 1595971e163fSPeter Brune 1596971e163fSPeter Brune Logically Collective on SNES 1597971e163fSPeter Brune 1598d8d19677SJose E. Roman Input Parameters: 1599971e163fSPeter Brune + snes - SNES context 1600971e163fSPeter Brune - reset - whether to reset the counters or not 1601971e163fSPeter Brune 1602971e163fSPeter Brune Notes: 1603fa19ca70SBarry Smith This defaults to PETSC_TRUE 1604971e163fSPeter Brune 1605971e163fSPeter Brune Level: developer 1606971e163fSPeter Brune 1607734794cfSBarry Smith .seealso: SNESGetNumberFunctionEvals(), SNESGetLinearSolveIterations(), SNESGetNPC() 1608971e163fSPeter Brune @*/ 1609971e163fSPeter Brune PetscErrorCode SNESSetCountersReset(SNES snes,PetscBool reset) 1610971e163fSPeter Brune { 1611971e163fSPeter Brune PetscFunctionBegin; 1612971e163fSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1613971e163fSPeter Brune PetscValidLogicalCollectiveBool(snes,reset,2); 1614971e163fSPeter Brune snes->counters_reset = reset; 1615971e163fSPeter Brune PetscFunctionReturn(0); 1616971e163fSPeter Brune } 1617971e163fSPeter Brune 16182999313aSBarry Smith /*@ 16192999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 16202999313aSBarry Smith 16212999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 16222999313aSBarry Smith 16232999313aSBarry Smith Input Parameters: 16242999313aSBarry Smith + snes - the SNES context 16252999313aSBarry Smith - ksp - the KSP context 16262999313aSBarry Smith 16272999313aSBarry Smith Notes: 16282999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 16292999313aSBarry Smith so this routine is rarely needed. 16302999313aSBarry Smith 16312999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 16322999313aSBarry Smith decreased by one. 16332999313aSBarry Smith 16342999313aSBarry Smith Level: developer 16352999313aSBarry Smith 16362999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 16372999313aSBarry Smith @*/ 16387087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 16392999313aSBarry Smith { 16402999313aSBarry Smith PetscErrorCode ierr; 16412999313aSBarry Smith 16422999313aSBarry Smith PetscFunctionBegin; 16430700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16440700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 16452999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 16467dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1647906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 16482999313aSBarry Smith snes->ksp = ksp; 16492999313aSBarry Smith PetscFunctionReturn(0); 16502999313aSBarry Smith } 16512999313aSBarry Smith 16529b94acceSBarry Smith /* -----------------------------------------------------------*/ 165352baeb72SSatish Balay /*@ 16549b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 16559b94acceSBarry Smith 1656d083f849SBarry Smith Collective 1657c7afd0dbSLois Curfman McInnes 1658c7afd0dbSLois Curfman McInnes Input Parameters: 1659906ed7ccSBarry Smith . comm - MPI communicator 16609b94acceSBarry Smith 16619b94acceSBarry Smith Output Parameter: 16629b94acceSBarry Smith . outsnes - the new SNES context 16639b94acceSBarry Smith 1664c7afd0dbSLois Curfman McInnes Options Database Keys: 1665c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1666c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1667c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1668c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1669c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1670c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1671c1f60f51SBarry Smith 167236851e7fSLois Curfman McInnes Level: beginner 167336851e7fSLois Curfman McInnes 167495452b02SPatrick Sanan Developer Notes: 167595452b02SPatrick Sanan SNES always creates a KSP object even though many SNES methods do not use it. This is 1676efd4aadfSBarry Smith unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the 1677efd4aadfSBarry Smith particular method does use KSP and regulates if the information about the KSP is printed 1678efd4aadfSBarry Smith in SNESView(). TSSetFromOptions() does call SNESSetFromOptions() which can lead to users being confused 1679efd4aadfSBarry Smith by help messages about meaningless SNES options. 1680efd4aadfSBarry Smith 1681efd4aadfSBarry Smith SNES always creates the snes->kspconvctx even though it is used by only one type. This should 1682efd4aadfSBarry Smith be fixed. 1683efd4aadfSBarry Smith 16843d5a8a6aSBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner(), SNESSetLagJacobian() 1685a8054027SBarry Smith 16869b94acceSBarry Smith @*/ 16877087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 16889b94acceSBarry Smith { 1689dfbe8321SBarry Smith PetscErrorCode ierr; 16909b94acceSBarry Smith SNES snes; 1691fa9f3622SBarry Smith SNESKSPEW *kctx; 169237fcc0dbSBarry Smith 16933a40ed3dSBarry Smith PetscFunctionBegin; 1694ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 16950298fd71SBarry Smith *outsnes = NULL; 1696607a6623SBarry Smith ierr = SNESInitializePackage();CHKERRQ(ierr); 16978ba1e511SMatthew Knepley 169873107ff1SLisandro Dalcin ierr = PetscHeaderCreate(snes,SNES_CLASSID,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 16997adad957SLisandro Dalcin 17008d359177SBarry Smith snes->ops->converged = SNESConvergedDefault; 17012c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 170288976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 17039b94acceSBarry Smith snes->max_its = 50; 17049750a799SBarry Smith snes->max_funcs = 10000; 17059b94acceSBarry Smith snes->norm = 0.0; 1706c1e67a49SFande Kong snes->xnorm = 0.0; 1707c1e67a49SFande Kong snes->ynorm = 0.0; 1708365a6726SPeter Brune snes->normschedule = SNES_NORM_ALWAYS; 17096c67d002SPeter Brune snes->functype = SNES_FUNCTION_DEFAULT; 17103a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 17113a2046daSBarry Smith snes->rtol = 1.e-5; 17123a2046daSBarry Smith #else 1713b4874afaSBarry Smith snes->rtol = 1.e-8; 17143a2046daSBarry Smith #endif 1715b4874afaSBarry Smith snes->ttol = 0.0; 17163a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 17173a2046daSBarry Smith snes->abstol = 1.e-25; 17183a2046daSBarry Smith #else 171970441072SBarry Smith snes->abstol = 1.e-50; 17203a2046daSBarry Smith #endif 17217cd0ae37SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE) 17227cd0ae37SLisandro Dalcin snes->stol = 1.e-5; 17237cd0ae37SLisandro Dalcin #else 1724c60f73f4SPeter Brune snes->stol = 1.e-8; 17257cd0ae37SLisandro Dalcin #endif 17263a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 17273a2046daSBarry Smith snes->deltatol = 1.e-6; 17283a2046daSBarry Smith #else 17294b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 17303a2046daSBarry Smith #endif 1731e37c518bSBarry Smith snes->divtol = 1.e4; 1732e37c518bSBarry Smith snes->rnorm0 = 0; 17339b94acceSBarry Smith snes->nfuncs = 0; 173450ffb88aSMatthew Knepley snes->numFailures = 0; 173550ffb88aSMatthew Knepley snes->maxFailures = 1; 17367a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1737e35cf81dSBarry Smith snes->lagjacobian = 1; 173837ec4e1aSPeter Brune snes->jac_iter = 0; 173937ec4e1aSPeter Brune snes->lagjac_persist = PETSC_FALSE; 1740a8054027SBarry Smith snes->lagpreconditioner = 1; 174137ec4e1aSPeter Brune snes->pre_iter = 0; 174237ec4e1aSPeter Brune snes->lagpre_persist = PETSC_FALSE; 1743639f9d9dSBarry Smith snes->numbermonitors = 0; 1744c4421ceaSFande Kong snes->numberreasonviews = 0; 17459e5d0892SLisandro Dalcin snes->data = NULL; 17464dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1747186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 17486f24a144SLois Curfman McInnes snes->nwork = 0; 17499e5d0892SLisandro Dalcin snes->work = NULL; 175058c9b817SLisandro Dalcin snes->nvwork = 0; 17519e5d0892SLisandro Dalcin snes->vwork = NULL; 1752758f92a0SBarry Smith snes->conv_hist_len = 0; 1753758f92a0SBarry Smith snes->conv_hist_max = 0; 17540298fd71SBarry Smith snes->conv_hist = NULL; 17550298fd71SBarry Smith snes->conv_hist_its = NULL; 1756758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1757971e163fSPeter Brune snes->counters_reset = PETSC_TRUE; 1758e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1759184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 1760efd4aadfSBarry Smith snes->npcside = PC_RIGHT; 1761b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled = 0; 1762c40d0f55SPeter Brune 1763d8f46077SPeter Brune snes->mf = PETSC_FALSE; 1764d8f46077SPeter Brune snes->mf_operator = PETSC_FALSE; 1765d8f46077SPeter Brune snes->mf_version = 1; 1766d8f46077SPeter Brune 17673d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 17683d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 17693d4c4710SBarry Smith 1770349187a7SBarry Smith snes->vizerotolerance = 1.e-8; 177176bd3646SJed Brown snes->checkjacdomainerror = PetscDefined(USE_DEBUG) ? PETSC_TRUE : PETSC_FALSE; 1772349187a7SBarry Smith 17734fc747eaSLawrence Mitchell /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */ 17744fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 17754fc747eaSLawrence Mitchell 17769b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 1777b00a9115SJed Brown ierr = PetscNewLog(snes,&kctx);CHKERRQ(ierr); 1778f5af7f23SKarl Rupp 17799b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 17809b94acceSBarry Smith kctx->version = 2; 17819b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 17829b94acceSBarry Smith this was too large for some test cases */ 178375567043SBarry Smith kctx->rtol_last = 0.0; 17849b94acceSBarry Smith kctx->rtol_max = .9; 17859b94acceSBarry Smith kctx->gamma = 1.0; 178662d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 178771f87433Sdalcinl kctx->alpha2 = kctx->alpha; 17889b94acceSBarry Smith kctx->threshold = .1; 178975567043SBarry Smith kctx->lresid_last = 0.0; 179075567043SBarry Smith kctx->norm_last = 0.0; 17919b94acceSBarry Smith 17929b94acceSBarry Smith *outsnes = snes; 17933a40ed3dSBarry Smith PetscFunctionReturn(0); 17949b94acceSBarry Smith } 17959b94acceSBarry Smith 179688f0584fSBarry Smith /*MC 1797411c0326SBarry Smith SNESFunction - Functional form used to convey the nonlinear function to be solved by SNES 179888f0584fSBarry Smith 179988f0584fSBarry Smith Synopsis: 1800411c0326SBarry Smith #include "petscsnes.h" 1801411c0326SBarry Smith PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx); 180288f0584fSBarry Smith 18031843f636SBarry Smith Collective on snes 18041843f636SBarry Smith 180588f0584fSBarry Smith Input Parameters: 180688f0584fSBarry Smith + snes - the SNES context 180788f0584fSBarry Smith . x - state at which to evaluate residual 180888f0584fSBarry Smith - ctx - optional user-defined function context, passed in with SNESSetFunction() 180988f0584fSBarry Smith 181088f0584fSBarry Smith Output Parameter: 181188f0584fSBarry Smith . f - vector to put residual (function value) 181288f0584fSBarry Smith 1813878cb397SSatish Balay Level: intermediate 1814878cb397SSatish Balay 181588f0584fSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 181688f0584fSBarry Smith M*/ 181788f0584fSBarry Smith 18189b94acceSBarry Smith /*@C 18199b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 18209b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 18219b94acceSBarry Smith equations. 18229b94acceSBarry Smith 18233f9fe445SBarry Smith Logically Collective on SNES 1824fee21e36SBarry Smith 1825c7afd0dbSLois Curfman McInnes Input Parameters: 1826c7afd0dbSLois Curfman McInnes + snes - the SNES context 18276b7fb656SBarry Smith . r - vector to store function values, may be NULL 1828f8b49ee9SBarry Smith . f - function evaluation routine; see SNESFunction for calling sequence details 1829c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 18300298fd71SBarry Smith function evaluation routine (may be NULL) 18319b94acceSBarry Smith 18329b94acceSBarry Smith Notes: 18339b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 18349b94acceSBarry Smith $ f'(x) x = -f(x), 1835c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 18369b94acceSBarry Smith 183736851e7fSLois Curfman McInnes Level: beginner 183836851e7fSLois Curfman McInnes 1839bf388a1fSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard(), SNESFunction 18409b94acceSBarry Smith @*/ 1841f8b49ee9SBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx) 18429b94acceSBarry Smith { 184385385478SLisandro Dalcin PetscErrorCode ierr; 18446cab3a1bSJed Brown DM dm; 18456cab3a1bSJed Brown 18463a40ed3dSBarry Smith PetscFunctionBegin; 18470700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1848d2a683ecSLisandro Dalcin if (r) { 1849d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1850d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 185185385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 18526bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 185385385478SLisandro Dalcin snes->vec_func = r; 1854d2a683ecSLisandro Dalcin } 18556cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1856f8b49ee9SBarry Smith ierr = DMSNESSetFunction(dm,f,ctx);CHKERRQ(ierr); 1857bbc1464cSBarry Smith if (f == SNESPicardComputeFunction) { 1858bbc1464cSBarry Smith ierr = DMSNESSetMFFunction(dm,SNESPicardComputeMFFunction,ctx);CHKERRQ(ierr); 1859bbc1464cSBarry Smith } 18603a40ed3dSBarry Smith PetscFunctionReturn(0); 18619b94acceSBarry Smith } 18629b94acceSBarry Smith 1863e4ed7901SPeter Brune /*@C 1864e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1865e4ed7901SPeter Brune function norm at the initialization of the method. In some 1866e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1867e4ed7901SPeter Brune SNESSolve. This function allows one to avoid a redundant call 1868e4ed7901SPeter Brune to SNESComputeFunction in that case. 1869e4ed7901SPeter Brune 1870e4ed7901SPeter Brune Logically Collective on SNES 1871e4ed7901SPeter Brune 1872e4ed7901SPeter Brune Input Parameters: 1873e4ed7901SPeter Brune + snes - the SNES context 1874e4ed7901SPeter Brune - f - vector to store function value 1875e4ed7901SPeter Brune 1876e4ed7901SPeter Brune Notes: 1877e4ed7901SPeter Brune This should not be modified during the solution procedure. 1878e4ed7901SPeter Brune 1879e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1880e4ed7901SPeter Brune 1881e4ed7901SPeter Brune Level: developer 1882e4ed7901SPeter Brune 1883e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm() 1884e4ed7901SPeter Brune @*/ 1885e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1886e4ed7901SPeter Brune { 1887e4ed7901SPeter Brune PetscErrorCode ierr; 1888e4ed7901SPeter Brune Vec vec_func; 1889e4ed7901SPeter Brune 1890e4ed7901SPeter Brune PetscFunctionBegin; 1891e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1892e4ed7901SPeter Brune PetscValidHeaderSpecific(f,VEC_CLASSID,2); 1893e4ed7901SPeter Brune PetscCheckSameComm(snes,1,f,2); 1894efd4aadfSBarry Smith if (snes->npcside== PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) { 1895902f982fSPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1896902f982fSPeter Brune PetscFunctionReturn(0); 1897902f982fSPeter Brune } 18980298fd71SBarry Smith ierr = SNESGetFunction(snes,&vec_func,NULL,NULL);CHKERRQ(ierr); 1899e4ed7901SPeter Brune ierr = VecCopy(f, vec_func);CHKERRQ(ierr); 1900f5af7f23SKarl Rupp 1901217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 1902e4ed7901SPeter Brune PetscFunctionReturn(0); 1903e4ed7901SPeter Brune } 1904e4ed7901SPeter Brune 1905534ebe21SPeter Brune /*@ 1906a5b23f4aSJose E. Roman SNESSetNormSchedule - Sets the SNESNormSchedule used in convergence and monitoring 1907534ebe21SPeter Brune of the SNES method. 1908534ebe21SPeter Brune 1909534ebe21SPeter Brune Logically Collective on SNES 1910534ebe21SPeter Brune 1911534ebe21SPeter Brune Input Parameters: 1912534ebe21SPeter Brune + snes - the SNES context 1913365a6726SPeter Brune - normschedule - the frequency of norm computation 1914534ebe21SPeter Brune 1915517f1916SMatthew G. Knepley Options Database Key: 1916a5b23f4aSJose E. Roman . -snes_norm_schedule <none, always, initialonly, finalonly, initialfinalonly> 1917517f1916SMatthew G. Knepley 1918534ebe21SPeter Brune Notes: 1919365a6726SPeter Brune Only certain SNES methods support certain SNESNormSchedules. Most require evaluation 1920534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1921534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1922a5b23f4aSJose E. Roman (SNESNGS) and the like do not require the norm of the function to be computed, and therefore 1923534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1924534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1925534ebe21SPeter Brune their solution. 1926534ebe21SPeter Brune 1927534ebe21SPeter Brune Level: developer 1928534ebe21SPeter Brune 1929365a6726SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1930534ebe21SPeter Brune @*/ 1931365a6726SPeter Brune PetscErrorCode SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule) 1932534ebe21SPeter Brune { 1933534ebe21SPeter Brune PetscFunctionBegin; 1934534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1935365a6726SPeter Brune snes->normschedule = normschedule; 1936534ebe21SPeter Brune PetscFunctionReturn(0); 1937534ebe21SPeter Brune } 1938534ebe21SPeter Brune 1939534ebe21SPeter Brune /*@ 1940a5b23f4aSJose E. Roman SNESGetNormSchedule - Gets the SNESNormSchedule used in convergence and monitoring 1941534ebe21SPeter Brune of the SNES method. 1942534ebe21SPeter Brune 1943534ebe21SPeter Brune Logically Collective on SNES 1944534ebe21SPeter Brune 1945534ebe21SPeter Brune Input Parameters: 1946534ebe21SPeter Brune + snes - the SNES context 1947365a6726SPeter Brune - normschedule - the type of the norm used 1948534ebe21SPeter Brune 1949534ebe21SPeter Brune Level: advanced 1950534ebe21SPeter Brune 1951365a6726SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1952534ebe21SPeter Brune @*/ 1953365a6726SPeter Brune PetscErrorCode SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule) 1954534ebe21SPeter Brune { 1955534ebe21SPeter Brune PetscFunctionBegin; 1956534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1957365a6726SPeter Brune *normschedule = snes->normschedule; 1958534ebe21SPeter Brune PetscFunctionReturn(0); 1959534ebe21SPeter Brune } 1960534ebe21SPeter Brune 1961c5ce4427SMatthew G. Knepley /*@ 1962c5ce4427SMatthew G. Knepley SNESSetFunctionNorm - Sets the last computed residual norm. 1963c5ce4427SMatthew G. Knepley 1964c5ce4427SMatthew G. Knepley Logically Collective on SNES 1965c5ce4427SMatthew G. Knepley 1966c5ce4427SMatthew G. Knepley Input Parameters: 1967c5ce4427SMatthew G. Knepley + snes - the SNES context 1968c5ce4427SMatthew G. Knepley 1969c5ce4427SMatthew G. Knepley - normschedule - the frequency of norm computation 1970c5ce4427SMatthew G. Knepley 1971c5ce4427SMatthew G. Knepley Level: developer 1972c5ce4427SMatthew G. Knepley 1973c5ce4427SMatthew G. Knepley .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1974c5ce4427SMatthew G. Knepley @*/ 1975c5ce4427SMatthew G. Knepley PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm) 1976c5ce4427SMatthew G. Knepley { 1977c5ce4427SMatthew G. Knepley PetscFunctionBegin; 1978c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1979c5ce4427SMatthew G. Knepley snes->norm = norm; 1980c5ce4427SMatthew G. Knepley PetscFunctionReturn(0); 1981c5ce4427SMatthew G. Knepley } 1982c5ce4427SMatthew G. Knepley 1983c5ce4427SMatthew G. Knepley /*@ 1984c5ce4427SMatthew G. Knepley SNESGetFunctionNorm - Gets the last computed norm of the residual 1985c5ce4427SMatthew G. Knepley 1986c5ce4427SMatthew G. Knepley Not Collective 1987c5ce4427SMatthew G. Knepley 1988c5ce4427SMatthew G. Knepley Input Parameter: 1989c5ce4427SMatthew G. Knepley . snes - the SNES context 1990c5ce4427SMatthew G. Knepley 1991c5ce4427SMatthew G. Knepley Output Parameter: 1992c5ce4427SMatthew G. Knepley . norm - the last computed residual norm 1993c5ce4427SMatthew G. Knepley 1994c5ce4427SMatthew G. Knepley Level: developer 1995c5ce4427SMatthew G. Knepley 1996c5ce4427SMatthew G. Knepley .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1997c5ce4427SMatthew G. Knepley @*/ 1998c5ce4427SMatthew G. Knepley PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm) 1999c5ce4427SMatthew G. Knepley { 2000c5ce4427SMatthew G. Knepley PetscFunctionBegin; 2001c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2002c5ce4427SMatthew G. Knepley PetscValidPointer(norm, 2); 2003c5ce4427SMatthew G. Knepley *norm = snes->norm; 2004c5ce4427SMatthew G. Knepley PetscFunctionReturn(0); 2005c5ce4427SMatthew G. Knepley } 2006c5ce4427SMatthew G. Knepley 2007c1e67a49SFande Kong /*@ 2008c1e67a49SFande Kong SNESGetUpdateNorm - Gets the last computed norm of the Newton update 2009c1e67a49SFande Kong 2010c1e67a49SFande Kong Not Collective 2011c1e67a49SFande Kong 2012c1e67a49SFande Kong Input Parameter: 2013c1e67a49SFande Kong . snes - the SNES context 2014c1e67a49SFande Kong 2015c1e67a49SFande Kong Output Parameter: 2016c1e67a49SFande Kong . ynorm - the last computed update norm 2017c1e67a49SFande Kong 2018c1e67a49SFande Kong Level: developer 2019c1e67a49SFande Kong 2020c1e67a49SFande Kong .seealso: SNESSetNormSchedule(), SNESComputeFunction(), SNESGetFunctionNorm() 2021c1e67a49SFande Kong @*/ 2022c1e67a49SFande Kong PetscErrorCode SNESGetUpdateNorm(SNES snes, PetscReal *ynorm) 2023c1e67a49SFande Kong { 2024c1e67a49SFande Kong PetscFunctionBegin; 2025c1e67a49SFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2026c1e67a49SFande Kong PetscValidPointer(ynorm, 2); 2027c1e67a49SFande Kong *ynorm = snes->ynorm; 2028c1e67a49SFande Kong PetscFunctionReturn(0); 2029c1e67a49SFande Kong } 2030c1e67a49SFande Kong 2031c1e67a49SFande Kong /*@ 20324591eaf2SFande Kong SNESGetSolutionNorm - Gets the last computed norm of the solution 2033c1e67a49SFande Kong 2034c1e67a49SFande Kong Not Collective 2035c1e67a49SFande Kong 2036c1e67a49SFande Kong Input Parameter: 2037c1e67a49SFande Kong . snes - the SNES context 2038c1e67a49SFande Kong 2039c1e67a49SFande Kong Output Parameter: 2040c1e67a49SFande Kong . xnorm - the last computed solution norm 2041c1e67a49SFande Kong 2042c1e67a49SFande Kong Level: developer 2043c1e67a49SFande Kong 2044c1e67a49SFande Kong .seealso: SNESSetNormSchedule(), SNESComputeFunction(), SNESGetFunctionNorm(), SNESGetUpdateNorm() 2045c1e67a49SFande Kong @*/ 2046c1e67a49SFande Kong PetscErrorCode SNESGetSolutionNorm(SNES snes, PetscReal *xnorm) 2047c1e67a49SFande Kong { 2048c1e67a49SFande Kong PetscFunctionBegin; 2049c1e67a49SFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2050c1e67a49SFande Kong PetscValidPointer(xnorm, 2); 2051c1e67a49SFande Kong *xnorm = snes->xnorm; 2052c1e67a49SFande Kong PetscFunctionReturn(0); 2053c1e67a49SFande Kong } 2054c1e67a49SFande Kong 205547073ea2SPeter Brune /*@C 2056a5b23f4aSJose E. Roman SNESSetFunctionType - Sets the SNESNormSchedule used in convergence and monitoring 205747073ea2SPeter Brune of the SNES method. 205847073ea2SPeter Brune 205947073ea2SPeter Brune Logically Collective on SNES 206047073ea2SPeter Brune 206147073ea2SPeter Brune Input Parameters: 206247073ea2SPeter Brune + snes - the SNES context 206347073ea2SPeter Brune - normschedule - the frequency of norm computation 206447073ea2SPeter Brune 206547073ea2SPeter Brune Notes: 206647073ea2SPeter Brune Only certain SNES methods support certain SNESNormSchedules. Most require evaluation 206747073ea2SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 206847073ea2SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 2069a5b23f4aSJose E. Roman (SNESNGS) and the like do not require the norm of the function to be computed, and therefore 207047073ea2SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 207147073ea2SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 207247073ea2SPeter Brune their solution. 207347073ea2SPeter Brune 207447073ea2SPeter Brune Level: developer 207547073ea2SPeter Brune 207647073ea2SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 207747073ea2SPeter Brune @*/ 207847073ea2SPeter Brune PetscErrorCode SNESSetFunctionType(SNES snes, SNESFunctionType type) 207947073ea2SPeter Brune { 208047073ea2SPeter Brune PetscFunctionBegin; 208147073ea2SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 208247073ea2SPeter Brune snes->functype = type; 208347073ea2SPeter Brune PetscFunctionReturn(0); 208447073ea2SPeter Brune } 208547073ea2SPeter Brune 208647073ea2SPeter Brune /*@C 2087a5b23f4aSJose E. Roman SNESGetFunctionType - Gets the SNESNormSchedule used in convergence and monitoring 208847073ea2SPeter Brune of the SNES method. 208947073ea2SPeter Brune 209047073ea2SPeter Brune Logically Collective on SNES 209147073ea2SPeter Brune 209247073ea2SPeter Brune Input Parameters: 209347073ea2SPeter Brune + snes - the SNES context 209447073ea2SPeter Brune - normschedule - the type of the norm used 209547073ea2SPeter Brune 209647073ea2SPeter Brune Level: advanced 209747073ea2SPeter Brune 209847073ea2SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 209947073ea2SPeter Brune @*/ 210047073ea2SPeter Brune PetscErrorCode SNESGetFunctionType(SNES snes, SNESFunctionType *type) 210147073ea2SPeter Brune { 210247073ea2SPeter Brune PetscFunctionBegin; 210347073ea2SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 210447073ea2SPeter Brune *type = snes->functype; 2105534ebe21SPeter Brune PetscFunctionReturn(0); 2106534ebe21SPeter Brune } 2107534ebe21SPeter Brune 2108bf388a1fSBarry Smith /*MC 2109be95d8f1SBarry Smith SNESNGSFunction - function used to convey a Gauss-Seidel sweep on the nonlinear function 2110bf388a1fSBarry Smith 2111bf388a1fSBarry Smith Synopsis: 2112aaa7dc30SBarry Smith #include <petscsnes.h> 2113be95d8f1SBarry Smith $ SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx); 2114bf388a1fSBarry Smith 21151843f636SBarry Smith Collective on snes 21161843f636SBarry Smith 21171843f636SBarry Smith Input Parameters: 2118bf388a1fSBarry Smith + X - solution vector 2119bf388a1fSBarry Smith . B - RHS vector 2120bf388a1fSBarry Smith - ctx - optional user-defined Gauss-Seidel context 2121bf388a1fSBarry Smith 21221843f636SBarry Smith Output Parameter: 21231843f636SBarry Smith . X - solution vector 21241843f636SBarry Smith 2125878cb397SSatish Balay Level: intermediate 2126878cb397SSatish Balay 2127be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESGetNGS() 2128bf388a1fSBarry Smith M*/ 2129bf388a1fSBarry Smith 2130c79ef259SPeter Brune /*@C 2131be95d8f1SBarry Smith SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for 2132c79ef259SPeter Brune use with composed nonlinear solvers. 2133c79ef259SPeter Brune 2134c79ef259SPeter Brune Input Parameters: 2135c79ef259SPeter Brune + snes - the SNES context 2136be95d8f1SBarry Smith . f - function evaluation routine to apply Gauss-Seidel see SNESNGSFunction 2137c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 21380298fd71SBarry Smith smoother evaluation routine (may be NULL) 2139c79ef259SPeter Brune 2140c79ef259SPeter Brune Notes: 2141be95d8f1SBarry Smith The NGS routines are used by the composed nonlinear solver to generate 2142c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 2143c79ef259SPeter Brune 2144d28543b3SPeter Brune Level: intermediate 2145c79ef259SPeter Brune 2146be95d8f1SBarry Smith .seealso: SNESGetFunction(), SNESComputeNGS() 2147c79ef259SPeter Brune @*/ 2148be95d8f1SBarry Smith PetscErrorCode SNESSetNGS(SNES snes,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx) 21496cab3a1bSJed Brown { 21506cab3a1bSJed Brown PetscErrorCode ierr; 21516cab3a1bSJed Brown DM dm; 21526cab3a1bSJed Brown 2153646217ecSPeter Brune PetscFunctionBegin; 21546cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 21556cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2156be95d8f1SBarry Smith ierr = DMSNESSetNGS(dm,f,ctx);CHKERRQ(ierr); 2157646217ecSPeter Brune PetscFunctionReturn(0); 2158646217ecSPeter Brune } 2159646217ecSPeter Brune 2160bbc1464cSBarry Smith /* 2161bbc1464cSBarry Smith This is used for -snes_mf_operator; it uses a duplicate of snes->jacobian_pre because snes->jacobian_pre cannot be 2162bbc1464cSBarry Smith changed during the KSPSolve() 2163bbc1464cSBarry Smith */ 2164bbc1464cSBarry Smith PetscErrorCode SNESPicardComputeMFFunction(SNES snes,Vec x,Vec f,void *ctx) 2165bbc1464cSBarry Smith { 2166bbc1464cSBarry Smith PetscErrorCode ierr; 2167bbc1464cSBarry Smith DM dm; 2168bbc1464cSBarry Smith DMSNES sdm; 2169bbc1464cSBarry Smith 2170bbc1464cSBarry Smith PetscFunctionBegin; 2171bbc1464cSBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2172bbc1464cSBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 2173bbc1464cSBarry Smith if (!sdm->ops->computepjacobian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard Jacobian."); 2174bbc1464cSBarry Smith /* A(x)*x - b(x) */ 2175bbc1464cSBarry Smith if (sdm->ops->computepfunction) { 2176bbc1464cSBarry Smith PetscStackPush("SNES Picard user function"); 2177bbc1464cSBarry Smith ierr = (*sdm->ops->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr); 2178bbc1464cSBarry Smith PetscStackPop; 2179bbc1464cSBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 2180bbc1464cSBarry Smith if (!snes->picard) { 21810df40c35SBarry Smith /* Cannot share nonzero pattern because of the possible use of SNESComputeJacobianDefault() */ 21820df40c35SBarry Smith ierr = MatDuplicate(snes->jacobian_pre,MAT_DO_NOT_COPY_VALUES,&snes->picard);CHKERRQ(ierr); 2183bbc1464cSBarry Smith } 2184bbc1464cSBarry Smith PetscStackPush("SNES Picard user Jacobian"); 2185bbc1464cSBarry Smith ierr = (*sdm->ops->computepjacobian)(snes,x,snes->picard,snes->picard,sdm->pctx);CHKERRQ(ierr); 2186bbc1464cSBarry Smith PetscStackPop; 2187bbc1464cSBarry Smith ierr = MatMultAdd(snes->picard,x,f,f);CHKERRQ(ierr); 2188bbc1464cSBarry Smith } else { 2189bbc1464cSBarry Smith PetscStackPush("SNES Picard user Jacobian"); 2190bbc1464cSBarry Smith ierr = (*sdm->ops->computepjacobian)(snes,x,snes->picard,snes->picard,sdm->pctx);CHKERRQ(ierr); 2191bbc1464cSBarry Smith PetscStackPop; 2192bbc1464cSBarry Smith ierr = MatMult(snes->picard,x,f);CHKERRQ(ierr); 2193bbc1464cSBarry Smith } 2194bbc1464cSBarry Smith PetscFunctionReturn(0); 2195bbc1464cSBarry Smith } 2196bbc1464cSBarry Smith 219725acbd8eSLisandro Dalcin PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 21988b0a5094SBarry Smith { 21998b0a5094SBarry Smith PetscErrorCode ierr; 2200e03ab78fSPeter Brune DM dm; 2201942e3340SBarry Smith DMSNES sdm; 22026cab3a1bSJed Brown 22038b0a5094SBarry Smith PetscFunctionBegin; 2204e03ab78fSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2205942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 220625acbd8eSLisandro Dalcin if (!sdm->ops->computepjacobian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard Jacobian."); 22078b0a5094SBarry Smith /* A(x)*x - b(x) */ 2208bbc1464cSBarry Smith if (sdm->ops->computepfunction) { 220925acbd8eSLisandro Dalcin PetscStackPush("SNES Picard user function"); 221022c6f798SBarry Smith ierr = (*sdm->ops->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr); 221125acbd8eSLisandro Dalcin PetscStackPop; 2212bbc1464cSBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 221325acbd8eSLisandro Dalcin PetscStackPush("SNES Picard user Jacobian"); 2214d1e9a80fSBarry Smith ierr = (*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx);CHKERRQ(ierr); 221525acbd8eSLisandro Dalcin PetscStackPop; 2216bbc1464cSBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 2217bbc1464cSBarry Smith } else { 2218bbc1464cSBarry Smith PetscStackPush("SNES Picard user Jacobian"); 2219bbc1464cSBarry Smith ierr = (*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx);CHKERRQ(ierr); 2220bbc1464cSBarry Smith PetscStackPop; 2221bbc1464cSBarry Smith ierr = MatMult(snes->jacobian_pre,x,f);CHKERRQ(ierr); 2222bbc1464cSBarry Smith } 22238b0a5094SBarry Smith PetscFunctionReturn(0); 22248b0a5094SBarry Smith } 22258b0a5094SBarry Smith 222625acbd8eSLisandro Dalcin PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat J,Mat B,void *ctx) 22278b0a5094SBarry Smith { 2228bbc1464cSBarry Smith PetscErrorCode ierr; 22298b0a5094SBarry Smith PetscFunctionBegin; 2230e03ab78fSPeter Brune /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */ 2231bbc1464cSBarry Smith /* must assembly if matrix-free to get the last SNES solution */ 2232bbc1464cSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2233bbc1464cSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 22348b0a5094SBarry Smith PetscFunctionReturn(0); 22358b0a5094SBarry Smith } 22368b0a5094SBarry Smith 22378b0a5094SBarry Smith /*@C 2238bbc1464cSBarry Smith SNESSetPicard - Use SNES to solve the system A(x) x = bp(x) + b via a Picard type iteration (Picard linearization) 22398b0a5094SBarry Smith 22408b0a5094SBarry Smith Logically Collective on SNES 22418b0a5094SBarry Smith 22428b0a5094SBarry Smith Input Parameters: 22438b0a5094SBarry Smith + snes - the SNES context 22446b7fb656SBarry Smith . r - vector to store function values, may be NULL 22456b7fb656SBarry Smith . bp - function evaluation routine, may be NULL 22466b7fb656SBarry Smith . Amat - matrix with which A(x) x - bp(x) - b is to be computed 2247e5d3d808SBarry Smith . Pmat - matrix from which preconditioner is computed (usually the same as Amat) 22486b7fb656SBarry Smith . J - function to compute matrix values, see SNESJacobianFunction() for details on its calling sequence 22496b7fb656SBarry Smith - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL) 22508b0a5094SBarry Smith 22518b0a5094SBarry Smith Notes: 22526b7fb656SBarry Smith It is often better to provide the nonlinear function F() and some approximation to its Jacobian directly and use 2253f450aa47SBarry Smith an approximate Newton solver. This interface is provided to allow porting/testing a previous Picard based code in PETSc before converting it to approximate Newton. 2254f450aa47SBarry Smith 22558b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 22568b0a5094SBarry Smith 22576b7fb656SBarry Smith $ Solves the equation A(x) x = bp(x) - b via the defect correction algorithm A(x^{n}) (x^{n+1} - x^{n}) = bp(x^{n}) + b - A(x^{n})x^{n} 22586b7fb656SBarry Smith $ Note that when an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = bp(x^{n}) + b iteration. 22598b0a5094SBarry Smith 22608b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 22618b0a5094SBarry Smith 22620d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 22636b7fb656SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = bp(x^n) + b 22648b0a5094SBarry Smith 22658b0a5094SBarry 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 22668b0a5094SBarry 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 22678b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 22688b0a5094SBarry Smith 22696b7fb656SBarry Smith When used with -snes_mf_operator this will run matrix-free Newton's method where the matrix-vector product is of the true Jacobian of A(x)x - bp(x) -b. 22706b7fb656SBarry Smith 22716b7fb656SBarry Smith When used with -snes_fd this will compute the true Jacobian (very slowly one column at at time) and thus represent Newton's method. 22726b7fb656SBarry Smith 22736b7fb656SBarry Smith When used with -snes_fd_coloring this will compute the Jacobian via coloring and thus represent a faster implementation of Newton's method. But the 22746b7fb656SBarry Smith the nonzero structure of the Jacobian is, in general larger than that of the Picard matrix A so you must provide in A the needed nonzero structure for the correct 22756b7fb656SBarry Smith coloring. When using DMDA this may mean creating the matrix A with DMCreateMatrix() using a wider stencil than strictly needed for A or with a DMDA_STENCIL_BOX. 22766b7fb656SBarry Smith See the commment in src/snes/tutorials/ex15.c. 2277bbc1464cSBarry Smith 2278f450aa47SBarry Smith Level: intermediate 22798b0a5094SBarry Smith 2280411c0326SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard(), SNESJacobianFunction 22818b0a5094SBarry Smith @*/ 2282bbc1464cSBarry Smith PetscErrorCode SNESSetPicard(SNES snes,Vec r,PetscErrorCode (*bp)(SNES,Vec,Vec,void*),Mat Amat, Mat Pmat, PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx) 22838b0a5094SBarry Smith { 22848b0a5094SBarry Smith PetscErrorCode ierr; 2285e03ab78fSPeter Brune DM dm; 2286e03ab78fSPeter Brune 22878b0a5094SBarry Smith PetscFunctionBegin; 22888b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2289e03ab78fSPeter Brune ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 2290bbc1464cSBarry Smith ierr = DMSNESSetPicard(dm,bp,J,ctx);CHKERRQ(ierr); 2291bbc1464cSBarry Smith ierr = DMSNESSetMFFunction(dm,SNESPicardComputeMFFunction,ctx);CHKERRQ(ierr); 22928b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 2293e5d3d808SBarry Smith ierr = SNESSetJacobian(snes,Amat,Pmat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 22948b0a5094SBarry Smith PetscFunctionReturn(0); 22958b0a5094SBarry Smith } 22968b0a5094SBarry Smith 22977971a8bfSPeter Brune /*@C 22987971a8bfSPeter Brune SNESGetPicard - Returns the context for the Picard iteration 22997971a8bfSPeter Brune 23007971a8bfSPeter Brune Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 23017971a8bfSPeter Brune 23027971a8bfSPeter Brune Input Parameter: 23037971a8bfSPeter Brune . snes - the SNES context 23047971a8bfSPeter Brune 2305d8d19677SJose E. Roman Output Parameters: 23060298fd71SBarry Smith + r - the function (or NULL) 2307f8b49ee9SBarry Smith . f - the function (or NULL); see SNESFunction for calling sequence details 2308e4357dc4SBarry Smith . Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL) 2309e4357dc4SBarry Smith . Pmat - the matrix from which the preconditioner will be constructed (or NULL) 2310f8b49ee9SBarry Smith . J - the function for matrix evaluation (or NULL); see SNESJacobianFunction for calling sequence details 23110298fd71SBarry Smith - ctx - the function context (or NULL) 23127971a8bfSPeter Brune 23137971a8bfSPeter Brune Level: advanced 23147971a8bfSPeter Brune 2315e4357dc4SBarry Smith .seealso: SNESSetPicard(), SNESGetFunction(), SNESGetJacobian(), SNESGetDM(), SNESFunction, SNESJacobianFunction 23167971a8bfSPeter Brune @*/ 2317d1e9a80fSBarry Smith PetscErrorCode SNESGetPicard(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),Mat *Amat, Mat *Pmat, PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx) 23187971a8bfSPeter Brune { 23197971a8bfSPeter Brune PetscErrorCode ierr; 23207971a8bfSPeter Brune DM dm; 23217971a8bfSPeter Brune 23227971a8bfSPeter Brune PetscFunctionBegin; 23237971a8bfSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23240298fd71SBarry Smith ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 2325e4357dc4SBarry Smith ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 23267971a8bfSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2327f8b49ee9SBarry Smith ierr = DMSNESGetPicard(dm,f,J,ctx);CHKERRQ(ierr); 23287971a8bfSPeter Brune PetscFunctionReturn(0); 23297971a8bfSPeter Brune } 23307971a8bfSPeter Brune 2331d25893d9SBarry Smith /*@C 2332d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 2333d25893d9SBarry Smith 2334d25893d9SBarry Smith Logically Collective on SNES 2335d25893d9SBarry Smith 2336d25893d9SBarry Smith Input Parameters: 2337d25893d9SBarry Smith + snes - the SNES context 2338d25893d9SBarry Smith . func - function evaluation routine 2339d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 23400298fd71SBarry Smith function evaluation routine (may be NULL) 2341d25893d9SBarry Smith 2342d25893d9SBarry Smith Calling sequence of func: 2343d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 2344d25893d9SBarry Smith 2345d25893d9SBarry Smith . f - function vector 2346d25893d9SBarry Smith - ctx - optional user-defined function context 2347d25893d9SBarry Smith 2348d25893d9SBarry Smith Level: intermediate 2349d25893d9SBarry Smith 2350d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 2351d25893d9SBarry Smith @*/ 2352d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 2353d25893d9SBarry Smith { 2354d25893d9SBarry Smith PetscFunctionBegin; 2355d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2356d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 2357d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 2358d25893d9SBarry Smith PetscFunctionReturn(0); 2359d25893d9SBarry Smith } 2360d25893d9SBarry Smith 23613ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 23621096aae1SMatthew Knepley /*@C 23631096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 23641096aae1SMatthew Knepley it assumes a zero right hand side. 23651096aae1SMatthew Knepley 23663f9fe445SBarry Smith Logically Collective on SNES 23671096aae1SMatthew Knepley 23681096aae1SMatthew Knepley Input Parameter: 23691096aae1SMatthew Knepley . snes - the SNES context 23701096aae1SMatthew Knepley 23711096aae1SMatthew Knepley Output Parameter: 23720298fd71SBarry Smith . rhs - the right hand side vector or NULL if the right hand side vector is null 23731096aae1SMatthew Knepley 23741096aae1SMatthew Knepley Level: intermediate 23751096aae1SMatthew Knepley 237685385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 23771096aae1SMatthew Knepley @*/ 23787087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 23791096aae1SMatthew Knepley { 23801096aae1SMatthew Knepley PetscFunctionBegin; 23810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23821096aae1SMatthew Knepley PetscValidPointer(rhs,2); 238385385478SLisandro Dalcin *rhs = snes->vec_rhs; 23841096aae1SMatthew Knepley PetscFunctionReturn(0); 23851096aae1SMatthew Knepley } 23861096aae1SMatthew Knepley 23879b94acceSBarry Smith /*@ 2388bf388a1fSBarry Smith SNESComputeFunction - Calls the function that has been set with SNESSetFunction(). 23899b94acceSBarry Smith 2390c7afd0dbSLois Curfman McInnes Collective on SNES 2391c7afd0dbSLois Curfman McInnes 23929b94acceSBarry Smith Input Parameters: 2393c7afd0dbSLois Curfman McInnes + snes - the SNES context 2394c7afd0dbSLois Curfman McInnes - x - input vector 23959b94acceSBarry Smith 23969b94acceSBarry Smith Output Parameter: 23973638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 23989b94acceSBarry Smith 23991bffabb2SLois Curfman McInnes Notes: 240036851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 2401bbc1464cSBarry Smith implementations, so users would not generally call this routine themselves. 240236851e7fSLois Curfman McInnes 240336851e7fSLois Curfman McInnes Level: developer 240436851e7fSLois Curfman McInnes 2405bbc1464cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction(), SNESComputeMFFunction() 24069b94acceSBarry Smith @*/ 24077087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 24089b94acceSBarry Smith { 2409dfbe8321SBarry Smith PetscErrorCode ierr; 24106cab3a1bSJed Brown DM dm; 2411942e3340SBarry Smith DMSNES sdm; 24129b94acceSBarry Smith 24133a40ed3dSBarry Smith PetscFunctionBegin; 24140700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 24150700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 24160700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2417c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 2418c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 241962796dfbSBarry Smith ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr); 2420184914b5SBarry Smith 24216cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2422942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 242332f3f7c2SPeter Brune if (sdm->ops->computefunction) { 242494db00ebSBarry Smith if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) { 2425ccf3c845SPeter Brune ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 242694db00ebSBarry Smith } 24278860a134SJunchao Zhang ierr = VecLockReadPush(x);CHKERRQ(ierr); 2428d64ed03dSBarry Smith PetscStackPush("SNES user function"); 24298ddeebeaSSteve Benbow /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 24308ddeebeaSSteve Benbow snes->domainerror = PETSC_FALSE; 243122c6f798SBarry Smith ierr = (*sdm->ops->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 2432d64ed03dSBarry Smith PetscStackPop; 24338860a134SJunchao Zhang ierr = VecLockReadPop(x);CHKERRQ(ierr); 243494db00ebSBarry Smith if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) { 2435ccf3c845SPeter Brune ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 243694db00ebSBarry Smith } 2437c90fad12SPeter Brune } else if (snes->vec_rhs) { 2438c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 2439644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 244085385478SLisandro Dalcin if (snes->vec_rhs) { 244185385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 24423ab0aad5SBarry Smith } 2443ae3c334cSLois Curfman McInnes snes->nfuncs++; 2444422a814eSBarry Smith /* 2445422a814eSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2446422a814eSBarry Smith propagate the value to all processes 2447422a814eSBarry Smith */ 2448422a814eSBarry Smith if (snes->domainerror) { 2449422a814eSBarry Smith ierr = VecSetInf(y);CHKERRQ(ierr); 2450422a814eSBarry Smith } 24513a40ed3dSBarry Smith PetscFunctionReturn(0); 24529b94acceSBarry Smith } 24539b94acceSBarry Smith 2454c79ef259SPeter Brune /*@ 2455bbc1464cSBarry Smith SNESComputeMFFunction - Calls the function that has been set with SNESSetMFFunction(). 2456bbc1464cSBarry Smith 2457bbc1464cSBarry Smith Collective on SNES 2458bbc1464cSBarry Smith 2459bbc1464cSBarry Smith Input Parameters: 2460bbc1464cSBarry Smith + snes - the SNES context 2461bbc1464cSBarry Smith - x - input vector 2462bbc1464cSBarry Smith 2463bbc1464cSBarry Smith Output Parameter: 2464bbc1464cSBarry Smith . y - function vector, as set by SNESSetMFFunction() 2465bbc1464cSBarry Smith 2466bbc1464cSBarry Smith Notes: 2467bbc1464cSBarry Smith SNESComputeMFFunction() is used within the matrix vector products called by the matrix created with MatCreateSNESMF() 2468bbc1464cSBarry Smith so users would not generally call this routine themselves. 2469bbc1464cSBarry Smith 2470bbc1464cSBarry Smith Since this function is intended for use with finite differencing it does not subtract the right hand side vector provided with SNESSolve() 2471bbc1464cSBarry Smith while SNESComputeFunction() does. As such, this routine cannot be used with MatMFFDSetBase() with a provided F function value even if it applies the 2472bbc1464cSBarry Smith same function as SNESComputeFunction() if a SNESSolve() right hand side vector is use because the two functions difference would include this right hand side function. 2473bbc1464cSBarry Smith 2474bbc1464cSBarry Smith Level: developer 2475bbc1464cSBarry Smith 2476bbc1464cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction(), SNESComputeFunction(), MatCreateSNESMF 2477bbc1464cSBarry Smith @*/ 2478bbc1464cSBarry Smith PetscErrorCode SNESComputeMFFunction(SNES snes,Vec x,Vec y) 2479bbc1464cSBarry Smith { 2480bbc1464cSBarry Smith PetscErrorCode ierr; 2481bbc1464cSBarry Smith DM dm; 2482bbc1464cSBarry Smith DMSNES sdm; 2483bbc1464cSBarry Smith 2484bbc1464cSBarry Smith PetscFunctionBegin; 2485bbc1464cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2486bbc1464cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2487bbc1464cSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2488bbc1464cSBarry Smith PetscCheckSameComm(snes,1,x,2); 2489bbc1464cSBarry Smith PetscCheckSameComm(snes,1,y,3); 2490bbc1464cSBarry Smith ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr); 2491bbc1464cSBarry Smith 2492bbc1464cSBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2493bbc1464cSBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 2494bbc1464cSBarry Smith ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 2495bbc1464cSBarry Smith ierr = VecLockReadPush(x);CHKERRQ(ierr); 2496bbc1464cSBarry Smith PetscStackPush("SNES user function"); 2497bbc1464cSBarry Smith /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 2498bbc1464cSBarry Smith snes->domainerror = PETSC_FALSE; 2499bbc1464cSBarry Smith ierr = (*sdm->ops->computemffunction)(snes,x,y,sdm->mffunctionctx);CHKERRQ(ierr); 2500bbc1464cSBarry Smith PetscStackPop; 2501bbc1464cSBarry Smith ierr = VecLockReadPop(x);CHKERRQ(ierr); 2502bbc1464cSBarry Smith ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 2503bbc1464cSBarry Smith snes->nfuncs++; 2504bbc1464cSBarry Smith /* 2505bbc1464cSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2506bbc1464cSBarry Smith propagate the value to all processes 2507bbc1464cSBarry Smith */ 2508bbc1464cSBarry Smith if (snes->domainerror) { 2509bbc1464cSBarry Smith ierr = VecSetInf(y);CHKERRQ(ierr); 2510bbc1464cSBarry Smith } 2511bbc1464cSBarry Smith PetscFunctionReturn(0); 2512bbc1464cSBarry Smith } 2513bbc1464cSBarry Smith 2514bbc1464cSBarry Smith /*@ 2515be95d8f1SBarry Smith SNESComputeNGS - Calls the Gauss-Seidel function that has been set with SNESSetNGS(). 2516c79ef259SPeter Brune 2517c79ef259SPeter Brune Collective on SNES 2518c79ef259SPeter Brune 2519c79ef259SPeter Brune Input Parameters: 2520c79ef259SPeter Brune + snes - the SNES context 2521c79ef259SPeter Brune . x - input vector 2522c79ef259SPeter Brune - b - rhs vector 2523c79ef259SPeter Brune 2524c79ef259SPeter Brune Output Parameter: 2525c79ef259SPeter Brune . x - new solution vector 2526c79ef259SPeter Brune 2527c79ef259SPeter Brune Notes: 2528be95d8f1SBarry Smith SNESComputeNGS() is typically used within composed nonlinear solver 2529c79ef259SPeter Brune implementations, so most users would not generally call this routine 2530c79ef259SPeter Brune themselves. 2531c79ef259SPeter Brune 2532c79ef259SPeter Brune Level: developer 2533c79ef259SPeter Brune 2534be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESComputeFunction() 2535c79ef259SPeter Brune @*/ 2536be95d8f1SBarry Smith PetscErrorCode SNESComputeNGS(SNES snes,Vec b,Vec x) 2537646217ecSPeter Brune { 2538646217ecSPeter Brune PetscErrorCode ierr; 25396cab3a1bSJed Brown DM dm; 2540942e3340SBarry Smith DMSNES sdm; 2541646217ecSPeter Brune 2542646217ecSPeter Brune PetscFunctionBegin; 2543646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2544064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(x,VEC_CLASSID,3); 2545064a246eSJacob Faibussowitsch if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 2546064a246eSJacob Faibussowitsch PetscCheckSameComm(snes,1,x,3); 2547064a246eSJacob Faibussowitsch if (b) PetscCheckSameComm(snes,1,b,2); 254862796dfbSBarry Smith if (b) {ierr = VecValidValues(b,2,PETSC_TRUE);CHKERRQ(ierr);} 2549be95d8f1SBarry Smith ierr = PetscLogEventBegin(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr); 25506cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2551942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 255222c6f798SBarry Smith if (sdm->ops->computegs) { 25538860a134SJunchao Zhang if (b) {ierr = VecLockReadPush(b);CHKERRQ(ierr);} 2554be95d8f1SBarry Smith PetscStackPush("SNES user NGS"); 255522c6f798SBarry Smith ierr = (*sdm->ops->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 2556646217ecSPeter Brune PetscStackPop; 25578860a134SJunchao Zhang if (b) {ierr = VecLockReadPop(b);CHKERRQ(ierr);} 2558be95d8f1SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve()."); 2559be95d8f1SBarry Smith ierr = PetscLogEventEnd(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr); 2560646217ecSPeter Brune PetscFunctionReturn(0); 2561646217ecSPeter Brune } 2562646217ecSPeter Brune 2563e885f1abSBarry Smith PetscErrorCode SNESTestJacobian(SNES snes) 2564e885f1abSBarry Smith { 256512837594SBarry Smith Mat A,B,C,D,jacobian; 2566e885f1abSBarry Smith Vec x = snes->vec_sol,f = snes->vec_func; 2567e885f1abSBarry Smith PetscErrorCode ierr; 2568e885f1abSBarry Smith PetscReal nrm,gnorm; 256981e7118cSBarry Smith PetscReal threshold = 1.e-5; 25700e276705SLisandro Dalcin MatType mattype; 2571e885f1abSBarry Smith PetscInt m,n,M,N; 2572e885f1abSBarry Smith void *functx; 25732cd624f9SStefano Zampini PetscBool complete_print = PETSC_FALSE,threshold_print = PETSC_FALSE,test = PETSC_FALSE,flg,istranspose; 25743325ff46SBarry Smith PetscViewer viewer,mviewer; 2575e885f1abSBarry Smith MPI_Comm comm; 2576e885f1abSBarry Smith PetscInt tabs; 257712837594SBarry Smith static PetscBool directionsprinted = PETSC_FALSE; 25783325ff46SBarry Smith PetscViewerFormat format; 2579e885f1abSBarry Smith 2580e885f1abSBarry Smith PetscFunctionBegin; 2581fc35ed60SBarry Smith ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 258212837594SBarry Smith ierr = PetscOptionsName("-snes_test_jacobian","Compare hand-coded and finite difference Jacobians","None",&test);CHKERRQ(ierr); 258312837594SBarry Smith ierr = PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold,NULL);CHKERRQ(ierr); 25843325ff46SBarry Smith ierr = PetscOptionsViewer("-snes_test_jacobian_view","View difference between hand-coded and finite difference Jacobians element entries","None",&mviewer,&format,&complete_print);CHKERRQ(ierr); 258518d89885SKarl Rupp if (!complete_print) { 2586455a5933SJed Brown ierr = PetscOptionsDeprecated("-snes_test_jacobian_display","-snes_test_jacobian_view","3.13",NULL);CHKERRQ(ierr); 258718d89885SKarl Rupp ierr = PetscOptionsViewer("-snes_test_jacobian_display","Display difference between hand-coded and finite difference Jacobians","None",&mviewer,&format,&complete_print);CHKERRQ(ierr); 258818d89885SKarl Rupp } 258918d89885SKarl Rupp /* for compatibility with PETSc 3.9 and older. */ 2590455a5933SJed Brown ierr = PetscOptionsDeprecated("-snes_test_jacobian_display_threshold","-snes_test_jacobian","3.13","-snes_test_jacobian accepts an optional threshold (since v3.10)");CHKERRQ(ierr); 259118d89885SKarl Rupp ierr = PetscOptionsReal("-snes_test_jacobian_display_threshold", "Display difference between hand-coded and finite difference Jacobians which exceed input threshold", "None", threshold, &threshold, &threshold_print);CHKERRQ(ierr); 2592e885f1abSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 2593e885f1abSBarry Smith if (!test) PetscFunctionReturn(0); 2594e885f1abSBarry Smith 2595e885f1abSBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2596e885f1abSBarry Smith ierr = PetscViewerASCIIGetStdout(comm,&viewer);CHKERRQ(ierr); 2597e885f1abSBarry Smith ierr = PetscViewerASCIIGetTab(viewer, &tabs);CHKERRQ(ierr); 2598e885f1abSBarry Smith ierr = PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel);CHKERRQ(ierr); 259912837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," ---------- Testing Jacobian -------------\n");CHKERRQ(ierr); 260012837594SBarry Smith if (!complete_print && !directionsprinted) { 260112837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n");CHKERRQ(ierr); 2602fc35ed60SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," of hand-coded and finite difference Jacobian entries greater than <threshold>.\n");CHKERRQ(ierr); 260312837594SBarry Smith } 260412837594SBarry Smith if (!directionsprinted) { 260512837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n");CHKERRQ(ierr); 2606e885f1abSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," O(1.e-8), the hand-coded Jacobian is probably correct.\n");CHKERRQ(ierr); 260712837594SBarry Smith directionsprinted = PETSC_TRUE; 2608e885f1abSBarry Smith } 26093325ff46SBarry Smith if (complete_print) { 26103325ff46SBarry Smith ierr = PetscViewerPushFormat(mviewer,format);CHKERRQ(ierr); 2611e885f1abSBarry Smith } 2612e885f1abSBarry Smith 261312837594SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)snes->jacobian,MATMFFD,&flg);CHKERRQ(ierr); 261412837594SBarry Smith if (!flg) jacobian = snes->jacobian; 261512837594SBarry Smith else jacobian = snes->jacobian_pre; 261612837594SBarry Smith 2617a82339d0SMatthew G. Knepley if (!x) { 2618a82339d0SMatthew G. Knepley ierr = MatCreateVecs(jacobian, &x, NULL);CHKERRQ(ierr); 2619a82339d0SMatthew G. Knepley } else { 2620a82339d0SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) x);CHKERRQ(ierr); 2621a82339d0SMatthew G. Knepley } 2622a82339d0SMatthew G. Knepley if (!f) { 2623a82339d0SMatthew G. Knepley ierr = VecDuplicate(x, &f);CHKERRQ(ierr); 2624a82339d0SMatthew G. Knepley } else { 2625a82339d0SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) f);CHKERRQ(ierr); 2626a82339d0SMatthew G. Knepley } 2627a82339d0SMatthew G. Knepley /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */ 2628a82339d0SMatthew G. Knepley ierr = SNESComputeFunction(snes,x,f);CHKERRQ(ierr); 2629a82339d0SMatthew G. Knepley ierr = VecDestroy(&f);CHKERRQ(ierr); 26302cd624f9SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)snes,SNESKSPTRANSPOSEONLY,&istranspose);CHKERRQ(ierr); 263112837594SBarry Smith while (jacobian) { 26322cd624f9SStefano Zampini Mat JT = NULL, Jsave = NULL; 26332cd624f9SStefano Zampini 26342cd624f9SStefano Zampini if (istranspose) { 26352cd624f9SStefano Zampini ierr = MatCreateTranspose(jacobian,&JT);CHKERRQ(ierr); 26362cd624f9SStefano Zampini Jsave = jacobian; 26372cd624f9SStefano Zampini jacobian = JT; 26382cd624f9SStefano Zampini } 26390e276705SLisandro Dalcin ierr = PetscObjectBaseTypeCompareAny((PetscObject)jacobian,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPISBAIJ,"");CHKERRQ(ierr); 264012837594SBarry Smith if (flg) { 264112837594SBarry Smith A = jacobian; 264212837594SBarry Smith ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 264312837594SBarry Smith } else { 26440bacdadaSStefano Zampini ierr = MatComputeOperator(jacobian,MATAIJ,&A);CHKERRQ(ierr); 264512837594SBarry Smith } 2646e885f1abSBarry Smith 26470e276705SLisandro Dalcin ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 2648e885f1abSBarry Smith ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 2649e885f1abSBarry Smith ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 26500e276705SLisandro Dalcin ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr); 26510e276705SLisandro Dalcin ierr = MatSetType(B,mattype);CHKERRQ(ierr); 2652e885f1abSBarry Smith ierr = MatSetSizes(B,m,n,M,N);CHKERRQ(ierr); 26530e276705SLisandro Dalcin ierr = MatSetBlockSizesFromMats(B,A,A);CHKERRQ(ierr); 2654e885f1abSBarry Smith ierr = MatSetUp(B);CHKERRQ(ierr); 2655e885f1abSBarry Smith ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 2656e885f1abSBarry Smith 2657e885f1abSBarry Smith ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr); 2658e885f1abSBarry Smith ierr = SNESComputeJacobianDefault(snes,x,B,B,functx);CHKERRQ(ierr); 265912837594SBarry Smith 266012837594SBarry Smith ierr = MatDuplicate(B,MAT_COPY_VALUES,&D);CHKERRQ(ierr); 266112837594SBarry Smith ierr = MatAYPX(D,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 266212837594SBarry Smith ierr = MatNorm(D,NORM_FROBENIUS,&nrm);CHKERRQ(ierr); 2663e885f1abSBarry Smith ierr = MatNorm(A,NORM_FROBENIUS,&gnorm);CHKERRQ(ierr); 266412837594SBarry Smith ierr = MatDestroy(&D);CHKERRQ(ierr); 266512837594SBarry Smith if (!gnorm) gnorm = 1; /* just in case */ 266612837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n",(double)(nrm/gnorm),(double)nrm);CHKERRQ(ierr); 266712837594SBarry Smith 2668e885f1abSBarry Smith if (complete_print) { 266912837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Hand-coded Jacobian ----------\n");CHKERRQ(ierr); 26701878987eSStefano Zampini ierr = MatView(A,mviewer);CHKERRQ(ierr); 267112837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Finite difference Jacobian ----------\n");CHKERRQ(ierr); 26723325ff46SBarry Smith ierr = MatView(B,mviewer);CHKERRQ(ierr); 2673e885f1abSBarry Smith } 2674e885f1abSBarry Smith 2675df10fb39SFande Kong if (threshold_print || complete_print) { 2676e885f1abSBarry Smith PetscInt Istart, Iend, *ccols, bncols, cncols, j, row; 2677e885f1abSBarry Smith PetscScalar *cvals; 2678e885f1abSBarry Smith const PetscInt *bcols; 2679e885f1abSBarry Smith const PetscScalar *bvals; 2680e885f1abSBarry Smith 2681e885f1abSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 26820e276705SLisandro Dalcin ierr = MatSetType(C,mattype);CHKERRQ(ierr); 2683e885f1abSBarry Smith ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr); 26840e276705SLisandro Dalcin ierr = MatSetBlockSizesFromMats(C,A,A);CHKERRQ(ierr); 2685e885f1abSBarry Smith ierr = MatSetUp(C);CHKERRQ(ierr); 2686e885f1abSBarry Smith ierr = MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 26870e276705SLisandro Dalcin 26880e276705SLisandro Dalcin ierr = MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 2689e885f1abSBarry Smith ierr = MatGetOwnershipRange(B,&Istart,&Iend);CHKERRQ(ierr); 2690e885f1abSBarry Smith 2691e885f1abSBarry Smith for (row = Istart; row < Iend; row++) { 2692e885f1abSBarry Smith ierr = MatGetRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr); 2693e885f1abSBarry Smith ierr = PetscMalloc2(bncols,&ccols,bncols,&cvals);CHKERRQ(ierr); 2694e885f1abSBarry Smith for (j = 0, cncols = 0; j < bncols; j++) { 269523a52b1dSBarry Smith if (PetscAbsScalar(bvals[j]) > threshold) { 2696e885f1abSBarry Smith ccols[cncols] = bcols[j]; 2697e885f1abSBarry Smith cvals[cncols] = bvals[j]; 2698e885f1abSBarry Smith cncols += 1; 2699e885f1abSBarry Smith } 2700e885f1abSBarry Smith } 2701e885f1abSBarry Smith if (cncols) { 2702e885f1abSBarry Smith ierr = MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES);CHKERRQ(ierr); 2703e885f1abSBarry Smith } 2704e885f1abSBarry Smith ierr = MatRestoreRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr); 2705e885f1abSBarry Smith ierr = PetscFree2(ccols,cvals);CHKERRQ(ierr); 2706e885f1abSBarry Smith } 2707e885f1abSBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2708e885f1abSBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 270912837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n",(double)threshold);CHKERRQ(ierr); 271018d89885SKarl Rupp ierr = MatView(C,complete_print ? mviewer : viewer);CHKERRQ(ierr); 2711e885f1abSBarry Smith ierr = MatDestroy(&C);CHKERRQ(ierr); 2712e885f1abSBarry Smith } 271312837594SBarry Smith ierr = MatDestroy(&A);CHKERRQ(ierr); 2714e885f1abSBarry Smith ierr = MatDestroy(&B);CHKERRQ(ierr); 27152cd624f9SStefano Zampini ierr = MatDestroy(&JT);CHKERRQ(ierr); 27162cd624f9SStefano Zampini if (Jsave) jacobian = Jsave; 271712837594SBarry Smith if (jacobian != snes->jacobian_pre) { 271812837594SBarry Smith jacobian = snes->jacobian_pre; 271912837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," ---------- Testing Jacobian for preconditioner -------------\n");CHKERRQ(ierr); 272012837594SBarry Smith } 272112837594SBarry Smith else jacobian = NULL; 272212837594SBarry Smith } 2723a82339d0SMatthew G. Knepley ierr = VecDestroy(&x);CHKERRQ(ierr); 27243325ff46SBarry Smith if (complete_print) { 27253325ff46SBarry Smith ierr = PetscViewerPopFormat(mviewer);CHKERRQ(ierr); 27263325ff46SBarry Smith } 2727a0c90127SFande Kong if (mviewer) { ierr = PetscViewerDestroy(&mviewer);CHKERRQ(ierr); } 2728e885f1abSBarry Smith ierr = PetscViewerASCIISetTab(viewer,tabs);CHKERRQ(ierr); 2729e885f1abSBarry Smith PetscFunctionReturn(0); 2730e885f1abSBarry Smith } 2731e885f1abSBarry Smith 273262fef451SLois Curfman McInnes /*@ 2733bf388a1fSBarry Smith SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian(). 273462fef451SLois Curfman McInnes 2735d083f849SBarry Smith Collective on SNES 2736c7afd0dbSLois Curfman McInnes 273762fef451SLois Curfman McInnes Input Parameters: 2738c7afd0dbSLois Curfman McInnes + snes - the SNES context 2739c7afd0dbSLois Curfman McInnes - x - input vector 274062fef451SLois Curfman McInnes 274162fef451SLois Curfman McInnes Output Parameters: 2742c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 2743d1e9a80fSBarry Smith - B - optional preconditioning matrix 2744fee21e36SBarry Smith 2745e35cf81dSBarry Smith Options Database Keys: 2746e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 2747693365a8SJed Brown . -snes_lag_jacobian <lag> 2748455a5933SJed Brown . -snes_test_jacobian <optional threshold> - compare the user provided Jacobian with one compute via finite differences to check for errors. If a threshold is given, display only those entries whose difference is greater than the threshold. 2749455a5933SJed Brown . -snes_test_jacobian_view - display the user provided Jacobian, the finite difference Jacobian and the difference between them to help users detect the location of errors in the user provided Jacobian 2750693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 2751693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 2752693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 27534c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 275494d6a431SBarry Smith . -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference 2755a5b23f4aSJose E. Roman . -snes_compare_coloring_display - Compute the finite difference Jacobian using coloring and display verbose differences 2756c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 2757c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2758c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2759a5b23f4aSJose E. Roman . -snes_compare_coloring_draw - Compute the finite difference Jacobian using coloring and draw differences 2760a5b23f4aSJose E. Roman - -snes_compare_coloring_draw_contour - Compute the finite difference Jacobian using coloring and show contours of matrices and differences 2761c01495d3SJed Brown 276262fef451SLois Curfman McInnes Notes: 276362fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 276462fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 276562fef451SLois Curfman McInnes 276695452b02SPatrick Sanan Developer Notes: 276795452b02SPatrick Sanan This has duplicative ways of checking the accuracy of the user provided Jacobian (see the options above). This is for historical reasons, the routine SNESTestJacobian() use to used 2768e885f1abSBarry Smith for with the SNESType of test that has been removed. 2769e885f1abSBarry Smith 277036851e7fSLois Curfman McInnes Level: developer 277136851e7fSLois Curfman McInnes 2772e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 277362fef451SLois Curfman McInnes @*/ 2774d1e9a80fSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat A,Mat B) 27759b94acceSBarry Smith { 2776dfbe8321SBarry Smith PetscErrorCode ierr; 2777ace3abfcSBarry Smith PetscBool flag; 27786cab3a1bSJed Brown DM dm; 2779942e3340SBarry Smith DMSNES sdm; 2780e0e3a89bSBarry Smith KSP ksp; 27813a40ed3dSBarry Smith 27823a40ed3dSBarry Smith PetscFunctionBegin; 27830700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 27840700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2785c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 278662796dfbSBarry Smith ierr = VecValidValues(X,2,PETSC_TRUE);CHKERRQ(ierr); 27876cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2788942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 27893232da50SPeter Brune 2790ce94432eSBarry Smith if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 2791ebd3b9afSBarry Smith 2792ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 2793ebd3b9afSBarry Smith 2794fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 2795fe3ffe1eSBarry Smith snes->lagjacobian = -1; 2796f5af7f23SKarl Rupp 2797fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 2798fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 2799e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 280094ab13aaSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr); 2801ebd3b9afSBarry Smith if (flag) { 280294ab13aaSBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 280394ab13aaSBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2804ebd3b9afSBarry Smith } 2805e35cf81dSBarry Smith PetscFunctionReturn(0); 280637ec4e1aSPeter Brune } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) { 2807e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 280894ab13aaSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr); 2809ebd3b9afSBarry Smith if (flag) { 281094ab13aaSBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 281194ab13aaSBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2812ebd3b9afSBarry Smith } 2813e35cf81dSBarry Smith PetscFunctionReturn(0); 2814e35cf81dSBarry Smith } 2815efd4aadfSBarry Smith if (snes->npc && snes->npcside== PC_LEFT) { 281694ab13aaSBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 281794ab13aaSBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2818d728fb7dSPeter Brune PetscFunctionReturn(0); 2819d728fb7dSPeter Brune } 2820e35cf81dSBarry Smith 282194ab13aaSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr); 28228860a134SJunchao Zhang ierr = VecLockReadPush(X);CHKERRQ(ierr); 2823d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 2824d1e9a80fSBarry Smith ierr = (*sdm->ops->computejacobian)(snes,X,A,B,sdm->jacobianctx);CHKERRQ(ierr); 2825d64ed03dSBarry Smith PetscStackPop; 28268860a134SJunchao Zhang ierr = VecLockReadPop(X);CHKERRQ(ierr); 282794ab13aaSBarry Smith ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr); 282828d58a37SPierre Jolivet 282928d58a37SPierre Jolivet /* attach latest linearization point to the preconditioning matrix */ 283028d58a37SPierre Jolivet ierr = PetscObjectCompose((PetscObject)B,"__SNES_latest_X",(PetscObject)X);CHKERRQ(ierr); 2831a8054027SBarry Smith 2832e0e3a89bSBarry Smith /* the next line ensures that snes->ksp exists */ 2833e0e3a89bSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 28343b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 28353b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 2836d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr); 28373b4f5425SBarry Smith snes->lagpreconditioner = -1; 28383b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 2839a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 2840d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr); 284137ec4e1aSPeter Brune } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) { 2842a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 2843d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr); 2844d1e9a80fSBarry Smith } else { 2845d1e9a80fSBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner\n");CHKERRQ(ierr); 2846d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr); 2847a8054027SBarry Smith } 2848a8054027SBarry Smith 2849e885f1abSBarry Smith ierr = SNESTestJacobian(snes);CHKERRQ(ierr); 28506d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 285194ab13aaSBarry Smith /* PetscValidHeaderSpecific(A,MAT_CLASSID,3); 285294ab13aaSBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,4); */ 2853693365a8SJed Brown { 2854693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 285516413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit",NULL,NULL,&flag);CHKERRQ(ierr); 285616413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr); 285716413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr); 285816413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_operator",NULL,NULL,&flag_operator);CHKERRQ(ierr); 2859693365a8SJed Brown if (flag || flag_draw || flag_contour) { 28600298fd71SBarry Smith Mat Bexp_mine = NULL,Bexp,FDexp; 2861693365a8SJed Brown PetscViewer vdraw,vstdout; 28626b3a5b13SJed Brown PetscBool flg; 2863693365a8SJed Brown if (flag_operator) { 28640bacdadaSStefano Zampini ierr = MatComputeOperator(A,MATAIJ,&Bexp_mine);CHKERRQ(ierr); 2865693365a8SJed Brown Bexp = Bexp_mine; 2866693365a8SJed Brown } else { 2867693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 2868b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompareAny((PetscObject)B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 286994ab13aaSBarry Smith if (flg) Bexp = B; 2870693365a8SJed Brown else { 2871693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 28720bacdadaSStefano Zampini ierr = MatComputeOperator(B,MATAIJ,&Bexp_mine);CHKERRQ(ierr); 2873693365a8SJed Brown Bexp = Bexp_mine; 2874693365a8SJed Brown } 2875693365a8SJed Brown } 2876693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 2877d1e9a80fSBarry Smith ierr = SNESComputeJacobianDefault(snes,X,FDexp,FDexp,NULL);CHKERRQ(ierr); 2878ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr); 2879693365a8SJed Brown if (flag_draw || flag_contour) { 28809e5d0892SLisandro Dalcin ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2881693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 28820298fd71SBarry Smith } else vdraw = NULL; 2883693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian");CHKERRQ(ierr); 2884693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 2885693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 2886693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 2887693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2888693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 2889693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2890693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 2891693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2892693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 2893693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2894693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 2895693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2896693365a8SJed Brown } 2897693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2898693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2899693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 2900693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 2901693365a8SJed Brown } 2902693365a8SJed Brown } 29034c30e9fbSJed Brown { 29046719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 29056719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 290616413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring",NULL,NULL,&flag);CHKERRQ(ierr); 290716413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_display",NULL,NULL,&flag_display);CHKERRQ(ierr); 290816413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr); 290916413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr); 291016413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",NULL,NULL,&flag_threshold);CHKERRQ(ierr); 291127b0f280SBarry Smith if (flag_threshold) { 2912c5929fdfSBarry Smith ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL);CHKERRQ(ierr); 2913c5929fdfSBarry Smith ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL);CHKERRQ(ierr); 291427b0f280SBarry Smith } 29156719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 29164c30e9fbSJed Brown Mat Bfd; 29174c30e9fbSJed Brown PetscViewer vdraw,vstdout; 2918335efc43SPeter Brune MatColoring coloring; 29194c30e9fbSJed Brown ISColoring iscoloring; 29204c30e9fbSJed Brown MatFDColoring matfdcoloring; 29214c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 29224c30e9fbSJed Brown void *funcctx; 29236719d8e4SJed Brown PetscReal norm1,norm2,normmax; 29244c30e9fbSJed Brown 292594ab13aaSBarry Smith ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 2926335efc43SPeter Brune ierr = MatColoringCreate(Bfd,&coloring);CHKERRQ(ierr); 2927335efc43SPeter Brune ierr = MatColoringSetType(coloring,MATCOLORINGSL);CHKERRQ(ierr); 2928335efc43SPeter Brune ierr = MatColoringSetFromOptions(coloring);CHKERRQ(ierr); 2929335efc43SPeter Brune ierr = MatColoringApply(coloring,&iscoloring);CHKERRQ(ierr); 2930335efc43SPeter Brune ierr = MatColoringDestroy(&coloring);CHKERRQ(ierr); 29314c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 2932f86b9fbaSHong Zhang ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 2933f86b9fbaSHong Zhang ierr = MatFDColoringSetUp(Bfd,iscoloring,matfdcoloring);CHKERRQ(ierr); 29344c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 29354c30e9fbSJed Brown 29364c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 29370298fd71SBarry Smith ierr = SNESGetFunction(snes,NULL,&func,&funcctx);CHKERRQ(ierr); 29384c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr); 29394c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 29404c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 29414c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 2942d1e9a80fSBarry Smith ierr = MatFDColoringApply(Bfd,matfdcoloring,X,snes);CHKERRQ(ierr); 29434c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 29444c30e9fbSJed Brown 2945ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr); 29464c30e9fbSJed Brown if (flag_draw || flag_contour) { 29479e5d0892SLisandro Dalcin ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 29484c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 29490298fd71SBarry Smith } else vdraw = NULL; 29504c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 295194ab13aaSBarry Smith if (flag_display) {ierr = MatView(B,vstdout);CHKERRQ(ierr);} 295294ab13aaSBarry Smith if (vdraw) {ierr = MatView(B,vdraw);CHKERRQ(ierr);} 29534c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 29546719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 29554c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 295694ab13aaSBarry Smith ierr = MatAYPX(Bfd,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 29574c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 29586719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 29594c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 296057622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%g normFrob=%g normmax=%g\n",(double)norm1,(double)norm2,(double)normmax);CHKERRQ(ierr); 29616719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 29624c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 29634c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 29644c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 29654c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 29664c30e9fbSJed Brown } 29674c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 29686719d8e4SJed Brown 29696719d8e4SJed Brown if (flag_threshold) { 29706719d8e4SJed Brown PetscInt bs,rstart,rend,i; 297194ab13aaSBarry Smith ierr = MatGetBlockSize(B,&bs);CHKERRQ(ierr); 297294ab13aaSBarry Smith ierr = MatGetOwnershipRange(B,&rstart,&rend);CHKERRQ(ierr); 29736719d8e4SJed Brown for (i=rstart; i<rend; i++) { 29746719d8e4SJed Brown const PetscScalar *ba,*ca; 29756719d8e4SJed Brown const PetscInt *bj,*cj; 29766719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 29776719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 297894ab13aaSBarry Smith ierr = MatGetRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr); 29796719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 298094ab13aaSBarry Smith if (bn != cn) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 29816719d8e4SJed Brown for (j=0; j<bn; j++) { 29826719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 29836719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 29846719d8e4SJed Brown maxentrycol = bj[j]; 29856719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 29866719d8e4SJed Brown } 29876719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 29886719d8e4SJed Brown maxdiffcol = bj[j]; 29896719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 29906719d8e4SJed Brown } 29916719d8e4SJed Brown if (rdiff > maxrdiff) { 29926719d8e4SJed Brown maxrdiffcol = bj[j]; 29936719d8e4SJed Brown maxrdiff = rdiff; 29946719d8e4SJed Brown } 29956719d8e4SJed Brown } 29966719d8e4SJed Brown if (maxrdiff > 1) { 299757622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(vstdout,"row %D (maxentry=%g at %D, maxdiff=%g at %D, maxrdiff=%g at %D):",i,(double)maxentry,maxentrycol,(double)maxdiff,maxdiffcol,(double)maxrdiff,maxrdiffcol);CHKERRQ(ierr); 29986719d8e4SJed Brown for (j=0; j<bn; j++) { 29996719d8e4SJed Brown PetscReal rdiff; 30006719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 30016719d8e4SJed Brown if (rdiff > 1) { 300257622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(vstdout," (%D,%g:%g)",bj[j],(double)PetscRealPart(ba[j]),(double)PetscRealPart(ca[j]));CHKERRQ(ierr); 30036719d8e4SJed Brown } 30046719d8e4SJed Brown } 30056719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 30066719d8e4SJed Brown } 300794ab13aaSBarry Smith ierr = MatRestoreRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr); 30086719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 30096719d8e4SJed Brown } 30106719d8e4SJed Brown } 30114c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 30124c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 30134c30e9fbSJed Brown } 30144c30e9fbSJed Brown } 30153a40ed3dSBarry Smith PetscFunctionReturn(0); 30169b94acceSBarry Smith } 30179b94acceSBarry Smith 3018bf388a1fSBarry Smith /*MC 3019411c0326SBarry Smith SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES 3020bf388a1fSBarry Smith 3021bf388a1fSBarry Smith Synopsis: 3022411c0326SBarry Smith #include "petscsnes.h" 3023411c0326SBarry Smith PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx); 3024bf388a1fSBarry Smith 30251843f636SBarry Smith Collective on snes 30261843f636SBarry Smith 30271843f636SBarry Smith Input Parameters: 30281843f636SBarry Smith + x - input vector, the Jacobian is to be computed at this value 3029bf388a1fSBarry Smith - ctx - [optional] user-defined Jacobian context 3030bf388a1fSBarry Smith 30311843f636SBarry Smith Output Parameters: 30321843f636SBarry Smith + Amat - the matrix that defines the (approximate) Jacobian 30331843f636SBarry Smith - Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 30341843f636SBarry Smith 3035878cb397SSatish Balay Level: intermediate 3036878cb397SSatish Balay 3037bf388a1fSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction(), SNESSetJacobian(), SNESGetJacobian() 3038bf388a1fSBarry Smith M*/ 3039bf388a1fSBarry Smith 30409b94acceSBarry Smith /*@C 30419b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 3042044dda88SLois Curfman McInnes location to store the matrix. 30439b94acceSBarry Smith 3044d083f849SBarry Smith Logically Collective on SNES 3045c7afd0dbSLois Curfman McInnes 30469b94acceSBarry Smith Input Parameters: 3047c7afd0dbSLois Curfman McInnes + snes - the SNES context 3048e5d3d808SBarry Smith . Amat - the matrix that defines the (approximate) Jacobian 3049e5d3d808SBarry Smith . Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 3050411c0326SBarry Smith . J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details 3051c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 30520298fd71SBarry Smith Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value) 30539b94acceSBarry Smith 30549b94acceSBarry Smith Notes: 3055e5d3d808SBarry Smith If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on 305616913363SBarry Smith each matrix. 305716913363SBarry Smith 3058895c21f2SBarry Smith If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null 3059895c21f2SBarry Smith space to Amat and the KSP solvers will automatically use that null space as needed during the solution process. 3060895c21f2SBarry Smith 30618d359177SBarry Smith If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument 3062a8a26c1eSJed Brown must be a MatFDColoring. 3063a8a26c1eSJed Brown 3064c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 3065c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 3066c3cc8fd1SJed Brown 306736851e7fSLois Curfman McInnes Level: beginner 306836851e7fSLois Curfman McInnes 3069411c0326SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESComputeJacobianDefaultColor(), MatStructure, J, 3070411c0326SBarry Smith SNESSetPicard(), SNESJacobianFunction 30719b94acceSBarry Smith @*/ 3072d1e9a80fSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx) 30739b94acceSBarry Smith { 3074dfbe8321SBarry Smith PetscErrorCode ierr; 30756cab3a1bSJed Brown DM dm; 30763a7fca6bSBarry Smith 30773a40ed3dSBarry Smith PetscFunctionBegin; 30780700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3079e5d3d808SBarry Smith if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 3080e5d3d808SBarry Smith if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 3081e5d3d808SBarry Smith if (Amat) PetscCheckSameComm(snes,1,Amat,2); 3082e5d3d808SBarry Smith if (Pmat) PetscCheckSameComm(snes,1,Pmat,3); 30836cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3084f8b49ee9SBarry Smith ierr = DMSNESSetJacobian(dm,J,ctx);CHKERRQ(ierr); 3085e5d3d808SBarry Smith if (Amat) { 3086e5d3d808SBarry Smith ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 30876bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 3088f5af7f23SKarl Rupp 3089e5d3d808SBarry Smith snes->jacobian = Amat; 30903a7fca6bSBarry Smith } 3091e5d3d808SBarry Smith if (Pmat) { 3092e5d3d808SBarry Smith ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr); 30936bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 3094f5af7f23SKarl Rupp 3095e5d3d808SBarry Smith snes->jacobian_pre = Pmat; 30963a7fca6bSBarry Smith } 30973a40ed3dSBarry Smith PetscFunctionReturn(0); 30989b94acceSBarry Smith } 309962fef451SLois Curfman McInnes 3100c2aafc4cSSatish Balay /*@C 3101b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 3102b4fd4287SBarry Smith provided context for evaluating the Jacobian. 3103b4fd4287SBarry Smith 3104c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 3105c7afd0dbSLois Curfman McInnes 3106b4fd4287SBarry Smith Input Parameter: 3107b4fd4287SBarry Smith . snes - the nonlinear solver context 3108b4fd4287SBarry Smith 3109b4fd4287SBarry Smith Output Parameters: 3110e5d3d808SBarry Smith + Amat - location to stash (approximate) Jacobian matrix (or NULL) 3111e5d3d808SBarry Smith . Pmat - location to stash matrix used to compute the preconditioner (or NULL) 3112411c0326SBarry Smith . J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence 31130298fd71SBarry Smith - ctx - location to stash Jacobian ctx (or NULL) 3114fee21e36SBarry Smith 311536851e7fSLois Curfman McInnes Level: advanced 311636851e7fSLois Curfman McInnes 3117411c0326SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian(), SNESJacobianFunction, SNESGetFunction() 3118b4fd4287SBarry Smith @*/ 3119d1e9a80fSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx) 3120b4fd4287SBarry Smith { 31216cab3a1bSJed Brown PetscErrorCode ierr; 31226cab3a1bSJed Brown DM dm; 3123942e3340SBarry Smith DMSNES sdm; 31246cab3a1bSJed Brown 31253a40ed3dSBarry Smith PetscFunctionBegin; 31260700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3127e5d3d808SBarry Smith if (Amat) *Amat = snes->jacobian; 3128e5d3d808SBarry Smith if (Pmat) *Pmat = snes->jacobian_pre; 31296cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3130942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 3131f8b49ee9SBarry Smith if (J) *J = sdm->ops->computejacobian; 31326cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 31333a40ed3dSBarry Smith PetscFunctionReturn(0); 3134b4fd4287SBarry Smith } 3135b4fd4287SBarry Smith 313658b371f3SBarry Smith static PetscErrorCode SNESSetDefaultComputeJacobian(SNES snes) 313758b371f3SBarry Smith { 313858b371f3SBarry Smith PetscErrorCode ierr; 313958b371f3SBarry Smith DM dm; 314058b371f3SBarry Smith DMSNES sdm; 314158b371f3SBarry Smith 314258b371f3SBarry Smith PetscFunctionBegin; 314358b371f3SBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 314458b371f3SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 314558b371f3SBarry Smith if (!sdm->ops->computejacobian && snes->jacobian_pre) { 314658b371f3SBarry Smith DM dm; 314758b371f3SBarry Smith PetscBool isdense,ismf; 314858b371f3SBarry Smith 314958b371f3SBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 315058b371f3SBarry Smith ierr = PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre,&isdense,MATSEQDENSE,MATMPIDENSE,MATDENSE,NULL);CHKERRQ(ierr); 315158b371f3SBarry Smith ierr = PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre,&ismf,MATMFFD,MATSHELL,NULL);CHKERRQ(ierr); 315258b371f3SBarry Smith if (isdense) { 315358b371f3SBarry Smith ierr = DMSNESSetJacobian(dm,SNESComputeJacobianDefault,NULL);CHKERRQ(ierr); 315458b371f3SBarry Smith } else if (!ismf) { 315558b371f3SBarry Smith ierr = DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr); 315658b371f3SBarry Smith } 315758b371f3SBarry Smith } 315858b371f3SBarry Smith PetscFunctionReturn(0); 315958b371f3SBarry Smith } 316058b371f3SBarry Smith 31619b94acceSBarry Smith /*@ 31629b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 3163272ac6f2SLois Curfman McInnes of a nonlinear solver. 31649b94acceSBarry Smith 3165fee21e36SBarry Smith Collective on SNES 3166fee21e36SBarry Smith 3167c7afd0dbSLois Curfman McInnes Input Parameters: 316870e92668SMatthew Knepley . snes - the SNES context 3169c7afd0dbSLois Curfman McInnes 3170272ac6f2SLois Curfman McInnes Notes: 3171272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 3172272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 3173272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 3174272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 3175272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 3176272ac6f2SLois Curfman McInnes 317736851e7fSLois Curfman McInnes Level: advanced 317836851e7fSLois Curfman McInnes 31799b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 31809b94acceSBarry Smith @*/ 31817087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 31829b94acceSBarry Smith { 3183dfbe8321SBarry Smith PetscErrorCode ierr; 31846cab3a1bSJed Brown DM dm; 3185942e3340SBarry Smith DMSNES sdm; 3186c35f09e5SBarry Smith SNESLineSearch linesearch, pclinesearch; 31876e2a1849SPeter Brune void *lsprectx,*lspostctx; 31886b2b7091SBarry Smith PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*); 31896b2b7091SBarry Smith PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*); 31906e2a1849SPeter Brune PetscErrorCode (*func)(SNES,Vec,Vec,void*); 31916e2a1849SPeter Brune Vec f,fpc; 31926e2a1849SPeter Brune void *funcctx; 3193d1e9a80fSBarry Smith PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*); 31941eb13d49SPeter Brune void *jacctx,*appctx; 319532b97717SPeter Brune Mat j,jpre; 31963a40ed3dSBarry Smith 31973a40ed3dSBarry Smith PetscFunctionBegin; 31980700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31994dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 3200e3ed9ee7SBarry Smith ierr = PetscLogEventBegin(SNES_Setup,snes,0,0,0);CHKERRQ(ierr); 32019b94acceSBarry Smith 32027adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 320304d7464bSBarry Smith ierr = SNESSetType(snes,SNESNEWTONLS);CHKERRQ(ierr); 320485385478SLisandro Dalcin } 320585385478SLisandro Dalcin 32060298fd71SBarry Smith ierr = SNESGetFunction(snes,&snes->vec_func,NULL,NULL);CHKERRQ(ierr); 320758c9b817SLisandro Dalcin 32086cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3209942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 3210ce94432eSBarry Smith if (!sdm->ops->computefunction) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object"); 321158b371f3SBarry Smith ierr = SNESSetDefaultComputeJacobian(snes);CHKERRQ(ierr); 321258b371f3SBarry Smith 32136cab3a1bSJed Brown if (!snes->vec_func) { 32146cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 3215214df951SJed Brown } 3216efd51863SBarry Smith 321722d28d08SBarry Smith if (!snes->ksp) { 321822d28d08SBarry Smith ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr); 321922d28d08SBarry Smith } 3220b710008aSBarry Smith 3221d8d34be6SBarry Smith if (snes->linesearch) { 32227601faf0SJed Brown ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 3223ed07d7d7SPeter Brune ierr = SNESLineSearchSetFunction(snes->linesearch,SNESComputeFunction);CHKERRQ(ierr); 3224d8d34be6SBarry Smith } 32259e764e56SPeter Brune 3226efd4aadfSBarry Smith if (snes->npc && (snes->npcside== PC_LEFT)) { 3227172a4300SPeter Brune snes->mf = PETSC_TRUE; 3228172a4300SPeter Brune snes->mf_operator = PETSC_FALSE; 3229172a4300SPeter Brune } 3230d8f46077SPeter Brune 3231efd4aadfSBarry Smith if (snes->npc) { 32326e2a1849SPeter Brune /* copy the DM over */ 32336e2a1849SPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3234efd4aadfSBarry Smith ierr = SNESSetDM(snes->npc,dm);CHKERRQ(ierr); 32356e2a1849SPeter Brune 32366e2a1849SPeter Brune ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr); 32376e2a1849SPeter Brune ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr); 3238efd4aadfSBarry Smith ierr = SNESSetFunction(snes->npc,fpc,func,funcctx);CHKERRQ(ierr); 323932b97717SPeter Brune ierr = SNESGetJacobian(snes,&j,&jpre,&jac,&jacctx);CHKERRQ(ierr); 3240efd4aadfSBarry Smith ierr = SNESSetJacobian(snes->npc,j,jpre,jac,jacctx);CHKERRQ(ierr); 32411eb13d49SPeter Brune ierr = SNESGetApplicationContext(snes,&appctx);CHKERRQ(ierr); 3242efd4aadfSBarry Smith ierr = SNESSetApplicationContext(snes->npc,appctx);CHKERRQ(ierr); 32436e2a1849SPeter Brune ierr = VecDestroy(&fpc);CHKERRQ(ierr); 32446e2a1849SPeter Brune 32456e2a1849SPeter Brune /* copy the function pointers over */ 3246efd4aadfSBarry Smith ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr); 32476e2a1849SPeter Brune 32486e2a1849SPeter Brune /* default to 1 iteration */ 3249efd4aadfSBarry Smith ierr = SNESSetTolerances(snes->npc,0.0,0.0,0.0,1,snes->npc->max_funcs);CHKERRQ(ierr); 3250efd4aadfSBarry Smith if (snes->npcside==PC_RIGHT) { 3251efd4aadfSBarry Smith ierr = SNESSetNormSchedule(snes->npc,SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); 3252a9936a0cSPeter Brune } else { 3253efd4aadfSBarry Smith ierr = SNESSetNormSchedule(snes->npc,SNES_NORM_NONE);CHKERRQ(ierr); 3254a9936a0cSPeter Brune } 3255efd4aadfSBarry Smith ierr = SNESSetFromOptions(snes->npc);CHKERRQ(ierr); 32566e2a1849SPeter Brune 32576e2a1849SPeter Brune /* copy the line search context over */ 3258d8d34be6SBarry Smith if (snes->linesearch && snes->npc->linesearch) { 32597601faf0SJed Brown ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); 3260efd4aadfSBarry Smith ierr = SNESGetLineSearch(snes->npc,&pclinesearch);CHKERRQ(ierr); 32616b2b7091SBarry Smith ierr = SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx);CHKERRQ(ierr); 32626b2b7091SBarry Smith ierr = SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx);CHKERRQ(ierr); 32636b2b7091SBarry Smith ierr = SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx);CHKERRQ(ierr); 32646b2b7091SBarry Smith ierr = SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx);CHKERRQ(ierr); 32656e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr); 32666e2a1849SPeter Brune } 3267d8d34be6SBarry Smith } 326832b97717SPeter Brune if (snes->mf) { 326932b97717SPeter Brune ierr = SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);CHKERRQ(ierr); 327032b97717SPeter Brune } 327132b97717SPeter Brune if (snes->ops->usercompute && !snes->user) { 327232b97717SPeter Brune ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 327332b97717SPeter Brune } 32746e2a1849SPeter Brune 327537ec4e1aSPeter Brune snes->jac_iter = 0; 327637ec4e1aSPeter Brune snes->pre_iter = 0; 327737ec4e1aSPeter Brune 3278410397dcSLisandro Dalcin if (snes->ops->setup) { 3279410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 3280410397dcSLisandro Dalcin } 328158c9b817SLisandro Dalcin 328258b371f3SBarry Smith ierr = SNESSetDefaultComputeJacobian(snes);CHKERRQ(ierr); 328358b371f3SBarry Smith 3284efd4aadfSBarry Smith if (snes->npc && (snes->npcside== PC_LEFT)) { 32856c67d002SPeter Brune if (snes->functype == SNES_FUNCTION_PRECONDITIONED) { 3286d8d34be6SBarry Smith if (snes->linesearch) { 328755d4788fSPeter Brune ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); 3288be95d8f1SBarry Smith ierr = SNESLineSearchSetFunction(linesearch,SNESComputeFunctionDefaultNPC);CHKERRQ(ierr); 32896c67d002SPeter Brune } 32906c67d002SPeter Brune } 3291d8d34be6SBarry Smith } 3292e3ed9ee7SBarry Smith ierr = PetscLogEventEnd(SNES_Setup,snes,0,0,0);CHKERRQ(ierr); 32937aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 32943a40ed3dSBarry Smith PetscFunctionReturn(0); 32959b94acceSBarry Smith } 32969b94acceSBarry Smith 329737596af1SLisandro Dalcin /*@ 329837596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 329937596af1SLisandro Dalcin 330037596af1SLisandro Dalcin Collective on SNES 330137596af1SLisandro Dalcin 330237596af1SLisandro Dalcin Input Parameter: 330337596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 330437596af1SLisandro Dalcin 3305d25893d9SBarry Smith Level: intermediate 3306d25893d9SBarry Smith 330795452b02SPatrick Sanan Notes: 330895452b02SPatrick Sanan Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 330937596af1SLisandro Dalcin 331037596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 331137596af1SLisandro Dalcin @*/ 331237596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 331337596af1SLisandro Dalcin { 331437596af1SLisandro Dalcin PetscErrorCode ierr; 331537596af1SLisandro Dalcin 331637596af1SLisandro Dalcin PetscFunctionBegin; 331737596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3318d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 3319d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 33200298fd71SBarry Smith snes->user = NULL; 3321d25893d9SBarry Smith } 3322efd4aadfSBarry Smith if (snes->npc) { 3323efd4aadfSBarry Smith ierr = SNESReset(snes->npc);CHKERRQ(ierr); 33248a23116dSBarry Smith } 33258a23116dSBarry Smith 332637596af1SLisandro Dalcin if (snes->ops->reset) { 332737596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 332837596af1SLisandro Dalcin } 33299e764e56SPeter Brune if (snes->ksp) { 33309e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 33319e764e56SPeter Brune } 33329e764e56SPeter Brune 33339e764e56SPeter Brune if (snes->linesearch) { 3334f1c6b773SPeter Brune ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 33359e764e56SPeter Brune } 33369e764e56SPeter Brune 33376bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 33386bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 33396bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 33406bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 33416bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 33426bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 3343bbc1464cSBarry Smith ierr = MatDestroy(&snes->picard);CHKERRQ(ierr); 3344c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 3345c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 3346f5af7f23SKarl Rupp 334740fdac6aSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 334840fdac6aSLawrence Mitchell 334937596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 335037596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 335137596af1SLisandro Dalcin PetscFunctionReturn(0); 335237596af1SLisandro Dalcin } 335337596af1SLisandro Dalcin 335452baeb72SSatish Balay /*@ 3355c4421ceaSFande Kong SNESConvergedReasonViewCancel - Clears all the reasonview functions for a SNES object. 3356c4421ceaSFande Kong 3357c4421ceaSFande Kong Collective on SNES 3358c4421ceaSFande Kong 3359c4421ceaSFande Kong Input Parameter: 3360c4421ceaSFande Kong . snes - iterative context obtained from SNESCreate() 3361c4421ceaSFande Kong 3362c4421ceaSFande Kong Level: intermediate 3363c4421ceaSFande Kong 3364c4421ceaSFande Kong .seealso: SNESCreate(), SNESDestroy(), SNESReset() 3365c4421ceaSFande Kong @*/ 3366c4421ceaSFande Kong PetscErrorCode SNESConvergedReasonViewCancel(SNES snes) 3367c4421ceaSFande Kong { 3368c4421ceaSFande Kong PetscErrorCode ierr; 3369c4421ceaSFande Kong PetscInt i; 3370c4421ceaSFande Kong 3371c4421ceaSFande Kong PetscFunctionBegin; 3372c4421ceaSFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3373c4421ceaSFande Kong for (i=0; i<snes->numberreasonviews; i++) { 3374c4421ceaSFande Kong if (snes->reasonviewdestroy[i]) { 3375c4421ceaSFande Kong ierr = (*snes->reasonviewdestroy[i])(&snes->reasonviewcontext[i]);CHKERRQ(ierr); 3376c4421ceaSFande Kong } 3377c4421ceaSFande Kong } 3378c4421ceaSFande Kong snes->numberreasonviews = 0; 3379c4421ceaSFande Kong PetscFunctionReturn(0); 3380c4421ceaSFande Kong } 3381c4421ceaSFande Kong 33821fb7b255SJunchao Zhang /*@C 33839b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 33849b94acceSBarry Smith with SNESCreate(). 33859b94acceSBarry Smith 3386c7afd0dbSLois Curfman McInnes Collective on SNES 3387c7afd0dbSLois Curfman McInnes 33889b94acceSBarry Smith Input Parameter: 33899b94acceSBarry Smith . snes - the SNES context 33909b94acceSBarry Smith 339136851e7fSLois Curfman McInnes Level: beginner 339236851e7fSLois Curfman McInnes 339363a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 33949b94acceSBarry Smith @*/ 33956bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 33969b94acceSBarry Smith { 33976849ba73SBarry Smith PetscErrorCode ierr; 33983a40ed3dSBarry Smith 33993a40ed3dSBarry Smith PetscFunctionBegin; 34006bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 34016bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 34029e5d0892SLisandro Dalcin if (--((PetscObject)(*snes))->refct > 0) {*snes = NULL; PetscFunctionReturn(0);} 3403d4bb536fSBarry Smith 34046bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 3405efd4aadfSBarry Smith ierr = SNESDestroy(&(*snes)->npc);CHKERRQ(ierr); 34066b8b9a38SLisandro Dalcin 3407e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 3408e04113cfSBarry Smith ierr = PetscObjectSAWsViewOff((PetscObject)*snes);CHKERRQ(ierr); 34096bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 34106d4c513bSLisandro Dalcin 341133124788SMatthew G. Knepley if ((*snes)->dm) {ierr = DMCoarsenHookRemove((*snes)->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,*snes);CHKERRQ(ierr);} 34126bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 34136bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 3414f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 34156b8b9a38SLisandro Dalcin 34166bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 34176bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 34186bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 34196b8b9a38SLisandro Dalcin } 3420071fcb05SBarry Smith if ((*snes)->conv_hist_alloc) { 3421071fcb05SBarry Smith ierr = PetscFree2((*snes)->conv_hist,(*snes)->conv_hist_its);CHKERRQ(ierr); 342258c9b817SLisandro Dalcin } 34236bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 3424c4421ceaSFande Kong ierr = SNESConvergedReasonViewCancel((*snes));CHKERRQ(ierr); 3425a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 34263a40ed3dSBarry Smith PetscFunctionReturn(0); 34279b94acceSBarry Smith } 34289b94acceSBarry Smith 34299b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 34309b94acceSBarry Smith 3431a8054027SBarry Smith /*@ 3432a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 3433a8054027SBarry Smith 34343f9fe445SBarry Smith Logically Collective on SNES 3435a8054027SBarry Smith 3436a8054027SBarry Smith Input Parameters: 3437a8054027SBarry Smith + snes - the SNES context 3438d8e291bfSBarry Smith - lag - 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 34393b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3440a8054027SBarry Smith 3441a8054027SBarry Smith Options Database Keys: 34423d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 34433d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 34443d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 34453d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3446a8054027SBarry Smith 3447a8054027SBarry Smith Notes: 3448a8054027SBarry Smith The default is 1 34493d5a8a6aSBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or SNESSetLagPreconditionerPersists() was called 3450d8e291bfSBarry Smith 3451d8e291bfSBarry Smith SNESSetLagPreconditionerPersists() allows using the same uniform lagging (for example every second solve) across multiple solves. 3452a8054027SBarry Smith 3453a8054027SBarry Smith Level: intermediate 3454a8054027SBarry Smith 34553d5a8a6aSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetLagPreconditionerPersists(), 34563d5a8a6aSBarry Smith SNESSetLagJacobianPersists() 3457a8054027SBarry Smith 3458a8054027SBarry Smith @*/ 34597087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 3460a8054027SBarry Smith { 3461a8054027SBarry Smith PetscFunctionBegin; 34620700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3463e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 3464e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 3465c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 3466a8054027SBarry Smith snes->lagpreconditioner = lag; 3467a8054027SBarry Smith PetscFunctionReturn(0); 3468a8054027SBarry Smith } 3469a8054027SBarry Smith 3470efd51863SBarry Smith /*@ 3471efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 3472efd51863SBarry Smith 3473efd51863SBarry Smith Logically Collective on SNES 3474efd51863SBarry Smith 3475efd51863SBarry Smith Input Parameters: 3476efd51863SBarry Smith + snes - the SNES context 3477efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 3478efd51863SBarry Smith 3479efd51863SBarry Smith Options Database Keys: 3480efd51863SBarry Smith . -snes_grid_sequence <steps> 3481efd51863SBarry Smith 3482efd51863SBarry Smith Level: intermediate 3483efd51863SBarry Smith 3484c0df2a02SJed Brown Notes: 3485c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 3486c0df2a02SJed Brown 3487fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetGridSequence() 3488efd51863SBarry Smith 3489efd51863SBarry Smith @*/ 3490efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 3491efd51863SBarry Smith { 3492efd51863SBarry Smith PetscFunctionBegin; 3493efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3494efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 3495efd51863SBarry Smith snes->gridsequence = steps; 3496efd51863SBarry Smith PetscFunctionReturn(0); 3497efd51863SBarry Smith } 3498efd51863SBarry Smith 3499fa19ca70SBarry Smith /*@ 3500fa19ca70SBarry Smith SNESGetGridSequence - gets the number of steps of grid sequencing that SNES does 3501fa19ca70SBarry Smith 3502fa19ca70SBarry Smith Logically Collective on SNES 3503fa19ca70SBarry Smith 3504fa19ca70SBarry Smith Input Parameter: 3505fa19ca70SBarry Smith . snes - the SNES context 3506fa19ca70SBarry Smith 3507fa19ca70SBarry Smith Output Parameter: 3508fa19ca70SBarry Smith . steps - the number of refinements to do, defaults to 0 3509fa19ca70SBarry Smith 3510fa19ca70SBarry Smith Options Database Keys: 3511fa19ca70SBarry Smith . -snes_grid_sequence <steps> 3512fa19ca70SBarry Smith 3513fa19ca70SBarry Smith Level: intermediate 3514fa19ca70SBarry Smith 3515fa19ca70SBarry Smith Notes: 3516fa19ca70SBarry Smith Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 3517fa19ca70SBarry Smith 3518fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetGridSequence() 3519fa19ca70SBarry Smith 3520fa19ca70SBarry Smith @*/ 3521fa19ca70SBarry Smith PetscErrorCode SNESGetGridSequence(SNES snes,PetscInt *steps) 3522fa19ca70SBarry Smith { 3523fa19ca70SBarry Smith PetscFunctionBegin; 3524fa19ca70SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3525fa19ca70SBarry Smith *steps = snes->gridsequence; 3526fa19ca70SBarry Smith PetscFunctionReturn(0); 3527fa19ca70SBarry Smith } 3528fa19ca70SBarry Smith 3529a8054027SBarry Smith /*@ 3530a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 3531a8054027SBarry Smith 35323f9fe445SBarry Smith Not Collective 3533a8054027SBarry Smith 3534a8054027SBarry Smith Input Parameter: 3535a8054027SBarry Smith . snes - the SNES context 3536a8054027SBarry Smith 3537a8054027SBarry Smith Output Parameter: 3538a8054027SBarry 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 35393b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3540a8054027SBarry Smith 3541a8054027SBarry Smith Options Database Keys: 35423d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 35433d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 35443d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 35453d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3546a8054027SBarry Smith 3547a8054027SBarry Smith Notes: 3548a8054027SBarry Smith The default is 1 3549a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3550a8054027SBarry Smith 3551a8054027SBarry Smith Level: intermediate 3552a8054027SBarry Smith 35533d5a8a6aSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner(), SNESSetLagJacobianPersists(), SNESSetLagPreconditionerPersists() 3554a8054027SBarry Smith 3555a8054027SBarry Smith @*/ 35567087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 3557a8054027SBarry Smith { 3558a8054027SBarry Smith PetscFunctionBegin; 35590700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3560a8054027SBarry Smith *lag = snes->lagpreconditioner; 3561a8054027SBarry Smith PetscFunctionReturn(0); 3562a8054027SBarry Smith } 3563a8054027SBarry Smith 3564e35cf81dSBarry Smith /*@ 3565e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 3566e35cf81dSBarry Smith often the preconditioner is rebuilt. 3567e35cf81dSBarry Smith 35683f9fe445SBarry Smith Logically Collective on SNES 3569e35cf81dSBarry Smith 3570e35cf81dSBarry Smith Input Parameters: 3571e35cf81dSBarry Smith + snes - the SNES context 3572e35cf81dSBarry 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 3573fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 3574e35cf81dSBarry Smith 3575e35cf81dSBarry Smith Options Database Keys: 35763d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 35773d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 35783d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 35793d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag. 3580e35cf81dSBarry Smith 3581e35cf81dSBarry Smith Notes: 3582e35cf81dSBarry Smith The default is 1 3583e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3584fe3ffe1eSBarry 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 3585fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 3586e35cf81dSBarry Smith 3587e35cf81dSBarry Smith Level: intermediate 3588e35cf81dSBarry Smith 35893d5a8a6aSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobianPersists(), SNESSetLagPreconditionerPersists() 3590e35cf81dSBarry Smith 3591e35cf81dSBarry Smith @*/ 35927087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 3593e35cf81dSBarry Smith { 3594e35cf81dSBarry Smith PetscFunctionBegin; 35950700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3596e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 3597e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 3598c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 3599e35cf81dSBarry Smith snes->lagjacobian = lag; 3600e35cf81dSBarry Smith PetscFunctionReturn(0); 3601e35cf81dSBarry Smith } 3602e35cf81dSBarry Smith 3603e35cf81dSBarry Smith /*@ 3604e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 3605e35cf81dSBarry Smith 36063f9fe445SBarry Smith Not Collective 3607e35cf81dSBarry Smith 3608e35cf81dSBarry Smith Input Parameter: 3609e35cf81dSBarry Smith . snes - the SNES context 3610e35cf81dSBarry Smith 3611e35cf81dSBarry Smith Output Parameter: 3612e35cf81dSBarry 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 3613e35cf81dSBarry Smith the Jacobian is built etc. 3614e35cf81dSBarry Smith 3615e35cf81dSBarry Smith Notes: 3616e35cf81dSBarry Smith The default is 1 36173d5a8a6aSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or SNESSetLagJacobianPersists() was called. 3618e35cf81dSBarry Smith 3619e35cf81dSBarry Smith Level: intermediate 3620e35cf81dSBarry Smith 36213d5a8a6aSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner(), SNESSetLagJacobianPersists(), SNESSetLagPreconditionerPersists() 3622e35cf81dSBarry Smith 3623e35cf81dSBarry Smith @*/ 36247087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 3625e35cf81dSBarry Smith { 3626e35cf81dSBarry Smith PetscFunctionBegin; 36270700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3628e35cf81dSBarry Smith *lag = snes->lagjacobian; 3629e35cf81dSBarry Smith PetscFunctionReturn(0); 3630e35cf81dSBarry Smith } 3631e35cf81dSBarry Smith 363237ec4e1aSPeter Brune /*@ 363337ec4e1aSPeter Brune SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves 363437ec4e1aSPeter Brune 363537ec4e1aSPeter Brune Logically collective on SNES 363637ec4e1aSPeter Brune 3637d8d19677SJose E. Roman Input Parameters: 363837ec4e1aSPeter Brune + snes - the SNES context 36399d7e2deaSPeter Brune - flg - jacobian lagging persists if true 364037ec4e1aSPeter Brune 364137ec4e1aSPeter Brune Options Database Keys: 36423d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 36433d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 36443d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 36453d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 36463d5a8a6aSBarry Smith 364795452b02SPatrick Sanan Notes: 364895452b02SPatrick Sanan This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by 364937ec4e1aSPeter Brune several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several 365037ec4e1aSPeter Brune timesteps may present huge efficiency gains. 365137ec4e1aSPeter Brune 365237ec4e1aSPeter Brune Level: developer 365337ec4e1aSPeter Brune 36543d5a8a6aSBarry Smith .seealso: SNESSetLagPreconditionerPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC(), SNESSetLagJacobianPersists() 365537ec4e1aSPeter Brune 365637ec4e1aSPeter Brune @*/ 365737ec4e1aSPeter Brune PetscErrorCode SNESSetLagJacobianPersists(SNES snes,PetscBool flg) 365837ec4e1aSPeter Brune { 365937ec4e1aSPeter Brune PetscFunctionBegin; 366037ec4e1aSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 366137ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes,flg,2); 366237ec4e1aSPeter Brune snes->lagjac_persist = flg; 366337ec4e1aSPeter Brune PetscFunctionReturn(0); 366437ec4e1aSPeter Brune } 366537ec4e1aSPeter Brune 366637ec4e1aSPeter Brune /*@ 3667d8e291bfSBarry Smith SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple nonlinear solves 366837ec4e1aSPeter Brune 366937ec4e1aSPeter Brune Logically Collective on SNES 367037ec4e1aSPeter Brune 3671d8d19677SJose E. Roman Input Parameters: 367237ec4e1aSPeter Brune + snes - the SNES context 36739d7e2deaSPeter Brune - flg - preconditioner lagging persists if true 367437ec4e1aSPeter Brune 367537ec4e1aSPeter Brune Options Database Keys: 36763d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 36773d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 36783d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 36793d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 368037ec4e1aSPeter Brune 368195452b02SPatrick Sanan Notes: 368295452b02SPatrick Sanan This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale 368337ec4e1aSPeter Brune by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over 368437ec4e1aSPeter Brune several timesteps may present huge efficiency gains. 368537ec4e1aSPeter Brune 368637ec4e1aSPeter Brune Level: developer 368737ec4e1aSPeter Brune 36883d5a8a6aSBarry Smith .seealso: SNESSetLagJacobianPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC(), SNESSetLagPreconditioner() 368937ec4e1aSPeter Brune 369037ec4e1aSPeter Brune @*/ 369137ec4e1aSPeter Brune PetscErrorCode SNESSetLagPreconditionerPersists(SNES snes,PetscBool flg) 369237ec4e1aSPeter Brune { 369337ec4e1aSPeter Brune PetscFunctionBegin; 369437ec4e1aSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 369537ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes,flg,2); 369637ec4e1aSPeter Brune snes->lagpre_persist = flg; 369737ec4e1aSPeter Brune PetscFunctionReturn(0); 369837ec4e1aSPeter Brune } 369937ec4e1aSPeter Brune 37009b94acceSBarry Smith /*@ 3701be5caee7SBarry Smith SNESSetForceIteration - force SNESSolve() to take at least one iteration regardless of the initial residual norm 3702be5caee7SBarry Smith 3703be5caee7SBarry Smith Logically Collective on SNES 3704be5caee7SBarry Smith 3705be5caee7SBarry Smith Input Parameters: 3706be5caee7SBarry Smith + snes - the SNES context 3707be5caee7SBarry Smith - force - PETSC_TRUE require at least one iteration 3708be5caee7SBarry Smith 3709be5caee7SBarry Smith Options Database Keys: 3710be5caee7SBarry Smith . -snes_force_iteration <force> - Sets forcing an iteration 3711be5caee7SBarry Smith 3712be5caee7SBarry Smith Notes: 3713be5caee7SBarry Smith This is used sometimes with TS to prevent TS from detecting a false steady state solution 3714be5caee7SBarry Smith 3715be5caee7SBarry Smith Level: intermediate 3716be5caee7SBarry Smith 3717be5caee7SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance() 3718be5caee7SBarry Smith @*/ 3719be5caee7SBarry Smith PetscErrorCode SNESSetForceIteration(SNES snes,PetscBool force) 3720be5caee7SBarry Smith { 3721be5caee7SBarry Smith PetscFunctionBegin; 3722be5caee7SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3723be5caee7SBarry Smith snes->forceiteration = force; 3724be5caee7SBarry Smith PetscFunctionReturn(0); 3725be5caee7SBarry Smith } 3726be5caee7SBarry Smith 372785216dc7SFande Kong /*@ 372885216dc7SFande Kong SNESGetForceIteration - Whether or not to force SNESSolve() take at least one iteration regardless of the initial residual norm 372985216dc7SFande Kong 373085216dc7SFande Kong Logically Collective on SNES 373185216dc7SFande Kong 373285216dc7SFande Kong Input Parameters: 373385216dc7SFande Kong . snes - the SNES context 373485216dc7SFande Kong 373585216dc7SFande Kong Output Parameter: 373685216dc7SFande Kong . force - PETSC_TRUE requires at least one iteration. 373785216dc7SFande Kong 373806dd6b0eSSatish Balay Level: intermediate 373906dd6b0eSSatish Balay 374085216dc7SFande Kong .seealso: SNESSetForceIteration(), SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance() 374185216dc7SFande Kong @*/ 374285216dc7SFande Kong PetscErrorCode SNESGetForceIteration(SNES snes,PetscBool *force) 374385216dc7SFande Kong { 374485216dc7SFande Kong PetscFunctionBegin; 374585216dc7SFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 374685216dc7SFande Kong *force = snes->forceiteration; 374785216dc7SFande Kong PetscFunctionReturn(0); 374885216dc7SFande Kong } 3749be5caee7SBarry Smith 3750be5caee7SBarry Smith /*@ 3751d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 37529b94acceSBarry Smith 37533f9fe445SBarry Smith Logically Collective on SNES 3754c7afd0dbSLois Curfman McInnes 37559b94acceSBarry Smith Input Parameters: 3756c7afd0dbSLois Curfman McInnes + snes - the SNES context 375770441072SBarry Smith . abstol - absolute convergence tolerance 375833174efeSLois Curfman McInnes . rtol - relative convergence tolerance 37595358d0d4SBarry Smith . stol - convergence tolerance in terms of the norm of the change in the solution between steps, || delta x || < stol*|| x || 376033174efeSLois Curfman McInnes . maxit - maximum number of iterations 3761e71169deSBarry Smith - maxf - maximum number of function evaluations (-1 indicates no limit) 3762fee21e36SBarry Smith 376333174efeSLois Curfman McInnes Options Database Keys: 376470441072SBarry Smith + -snes_atol <abstol> - Sets abstol 3765c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 3766c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 3767c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 3768c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 37699b94acceSBarry Smith 3770d7a720efSLois Curfman McInnes Notes: 37719b94acceSBarry Smith The default maximum number of iterations is 50. 37729b94acceSBarry Smith The default maximum number of function evaluations is 1000. 37739b94acceSBarry Smith 377436851e7fSLois Curfman McInnes Level: intermediate 377536851e7fSLois Curfman McInnes 3776be5caee7SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance(), SNESSetForceIteration() 37779b94acceSBarry Smith @*/ 37787087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 37799b94acceSBarry Smith { 37803a40ed3dSBarry Smith PetscFunctionBegin; 37810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3782c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 3783c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 3784c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 3785c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 3786c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 3787c5eb9154SBarry Smith 3788ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 378957622a8eSBarry Smith if (abstol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g must be non-negative",(double)abstol); 3790ab54825eSJed Brown snes->abstol = abstol; 3791ab54825eSJed Brown } 3792ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 379357622a8eSBarry Smith if (rtol < 0.0 || 1.0 <= rtol) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Relative tolerance %g must be non-negative and less than 1.0",(double)rtol); 3794ab54825eSJed Brown snes->rtol = rtol; 3795ab54825eSJed Brown } 3796ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 379757622a8eSBarry Smith if (stol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %g must be non-negative",(double)stol); 3798c60f73f4SPeter Brune snes->stol = stol; 3799ab54825eSJed Brown } 3800ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 3801ce94432eSBarry Smith if (maxit < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 3802ab54825eSJed Brown snes->max_its = maxit; 3803ab54825eSJed Brown } 3804ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 3805e71169deSBarry Smith if (maxf < -1) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be -1 or nonnegative",maxf); 3806ab54825eSJed Brown snes->max_funcs = maxf; 3807ab54825eSJed Brown } 380888976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 38093a40ed3dSBarry Smith PetscFunctionReturn(0); 38109b94acceSBarry Smith } 38119b94acceSBarry Smith 3812e4d06f11SPatrick Farrell /*@ 3813e4d06f11SPatrick Farrell SNESSetDivergenceTolerance - Sets the divergence tolerance used for the SNES divergence test. 3814e4d06f11SPatrick Farrell 3815e4d06f11SPatrick Farrell Logically Collective on SNES 3816e4d06f11SPatrick Farrell 3817e4d06f11SPatrick Farrell Input Parameters: 3818e4d06f11SPatrick Farrell + snes - the SNES context 3819e4d06f11SPatrick Farrell - divtol - the divergence tolerance. Use -1 to deactivate the test. 3820e4d06f11SPatrick Farrell 3821e4d06f11SPatrick Farrell Options Database Keys: 3822a2b725a8SWilliam Gropp . -snes_divergence_tolerance <divtol> - Sets divtol 3823e4d06f11SPatrick Farrell 3824e4d06f11SPatrick Farrell Notes: 3825e4d06f11SPatrick Farrell The default divergence tolerance is 1e4. 3826e4d06f11SPatrick Farrell 3827e4d06f11SPatrick Farrell Level: intermediate 3828e4d06f11SPatrick Farrell 3829e4d06f11SPatrick Farrell .seealso: SNESSetTolerances(), SNESGetDivergenceTolerance 3830e4d06f11SPatrick Farrell @*/ 3831e4d06f11SPatrick Farrell PetscErrorCode SNESSetDivergenceTolerance(SNES snes,PetscReal divtol) 3832e4d06f11SPatrick Farrell { 3833e4d06f11SPatrick Farrell PetscFunctionBegin; 3834e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3835e4d06f11SPatrick Farrell PetscValidLogicalCollectiveReal(snes,divtol,2); 3836e4d06f11SPatrick Farrell 3837e4d06f11SPatrick Farrell if (divtol != PETSC_DEFAULT) { 3838e4d06f11SPatrick Farrell snes->divtol = divtol; 3839e4d06f11SPatrick Farrell } 3840e4d06f11SPatrick Farrell else { 3841e4d06f11SPatrick Farrell snes->divtol = 1.0e4; 3842e4d06f11SPatrick Farrell } 3843e4d06f11SPatrick Farrell PetscFunctionReturn(0); 3844e4d06f11SPatrick Farrell } 3845e4d06f11SPatrick Farrell 38469b94acceSBarry Smith /*@ 384733174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 384833174efeSLois Curfman McInnes 3849c7afd0dbSLois Curfman McInnes Not Collective 3850c7afd0dbSLois Curfman McInnes 385133174efeSLois Curfman McInnes Input Parameters: 3852c7afd0dbSLois Curfman McInnes + snes - the SNES context 385385385478SLisandro Dalcin . atol - absolute convergence tolerance 385433174efeSLois Curfman McInnes . rtol - relative convergence tolerance 385533174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 385633174efeSLois Curfman McInnes of the change in the solution between steps 385733174efeSLois Curfman McInnes . maxit - maximum number of iterations 3858c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 3859fee21e36SBarry Smith 386033174efeSLois Curfman McInnes Notes: 38610298fd71SBarry Smith The user can specify NULL for any parameter that is not needed. 386233174efeSLois Curfman McInnes 386336851e7fSLois Curfman McInnes Level: intermediate 386436851e7fSLois Curfman McInnes 386533174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 386633174efeSLois Curfman McInnes @*/ 38677087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 386833174efeSLois Curfman McInnes { 38693a40ed3dSBarry Smith PetscFunctionBegin; 38700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 387185385478SLisandro Dalcin if (atol) *atol = snes->abstol; 387233174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 3873c60f73f4SPeter Brune if (stol) *stol = snes->stol; 387433174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 387533174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 38763a40ed3dSBarry Smith PetscFunctionReturn(0); 387733174efeSLois Curfman McInnes } 387833174efeSLois Curfman McInnes 3879e4d06f11SPatrick Farrell /*@ 3880e4d06f11SPatrick Farrell SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test. 3881e4d06f11SPatrick Farrell 3882e4d06f11SPatrick Farrell Not Collective 3883e4d06f11SPatrick Farrell 3884e4d06f11SPatrick Farrell Input Parameters: 3885e4d06f11SPatrick Farrell + snes - the SNES context 3886e4d06f11SPatrick Farrell - divtol - divergence tolerance 3887e4d06f11SPatrick Farrell 3888e4d06f11SPatrick Farrell Level: intermediate 3889e4d06f11SPatrick Farrell 3890e4d06f11SPatrick Farrell .seealso: SNESSetDivergenceTolerance() 3891e4d06f11SPatrick Farrell @*/ 3892e4d06f11SPatrick Farrell PetscErrorCode SNESGetDivergenceTolerance(SNES snes,PetscReal *divtol) 3893e4d06f11SPatrick Farrell { 3894e4d06f11SPatrick Farrell PetscFunctionBegin; 3895e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3896e4d06f11SPatrick Farrell if (divtol) *divtol = snes->divtol; 3897e4d06f11SPatrick Farrell PetscFunctionReturn(0); 3898e4d06f11SPatrick Farrell } 3899e4d06f11SPatrick Farrell 390033174efeSLois Curfman McInnes /*@ 39019b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 39029b94acceSBarry Smith 39033f9fe445SBarry Smith Logically Collective on SNES 3904fee21e36SBarry Smith 3905c7afd0dbSLois Curfman McInnes Input Parameters: 3906c7afd0dbSLois Curfman McInnes + snes - the SNES context 3907c7afd0dbSLois Curfman McInnes - tol - tolerance 3908c7afd0dbSLois Curfman McInnes 39099b94acceSBarry Smith Options Database Key: 3910c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 39119b94acceSBarry Smith 391236851e7fSLois Curfman McInnes Level: intermediate 391336851e7fSLois Curfman McInnes 39142492ecdbSBarry Smith .seealso: SNESSetTolerances() 39159b94acceSBarry Smith @*/ 39167087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 39179b94acceSBarry Smith { 39183a40ed3dSBarry Smith PetscFunctionBegin; 39190700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3920c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 39219b94acceSBarry Smith snes->deltatol = tol; 39223a40ed3dSBarry Smith PetscFunctionReturn(0); 39239b94acceSBarry Smith } 39249b94acceSBarry Smith 39256ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 39266ba87a44SLisandro Dalcin 39277087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 3928b271bb04SBarry Smith { 3929b271bb04SBarry Smith PetscDrawLG lg; 3930b271bb04SBarry Smith PetscErrorCode ierr; 3931b271bb04SBarry Smith PetscReal x,y,per; 3932b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 3933b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 3934b271bb04SBarry Smith PetscDraw draw; 3935b271bb04SBarry Smith 3936459f5d12SBarry Smith PetscFunctionBegin; 39374d4332d5SBarry Smith PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,4); 3938b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 3939b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3940b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3941b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 3942b271bb04SBarry Smith x = (PetscReal)n; 394377b4d14cSPeter Brune if (rnorm > 0.0) y = PetscLog10Real(rnorm); 394494c9c6d3SKarl Rupp else y = -15.0; 3945b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 39466934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 3947b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 39486934998bSLisandro Dalcin ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3949b271bb04SBarry Smith } 3950b271bb04SBarry Smith 3951b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 3952b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3953b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3954b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 3955b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 3956b271bb04SBarry Smith x = (PetscReal)n; 3957b271bb04SBarry Smith y = 100.0*per; 3958b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 39596934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 3960b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 39616934998bSLisandro Dalcin ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3962b271bb04SBarry Smith } 3963b271bb04SBarry Smith 3964b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 3965b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3966b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3967b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 3968b271bb04SBarry Smith x = (PetscReal)n; 3969b271bb04SBarry Smith y = (prev - rnorm)/prev; 3970b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 39716934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 3972b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 39736934998bSLisandro Dalcin ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3974b271bb04SBarry Smith } 3975b271bb04SBarry Smith 3976b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 3977b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3978b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3979b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 3980b271bb04SBarry Smith x = (PetscReal)n; 3981b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 3982b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 3983b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3984b271bb04SBarry Smith } 39856934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 3986b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 39876934998bSLisandro Dalcin ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3988b271bb04SBarry Smith } 3989b271bb04SBarry Smith prev = rnorm; 3990b271bb04SBarry Smith PetscFunctionReturn(0); 3991b271bb04SBarry Smith } 3992b271bb04SBarry Smith 3993228d79bcSJed Brown /*@ 3994228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 3995228d79bcSJed Brown 3996228d79bcSJed Brown Collective on SNES 3997228d79bcSJed Brown 3998228d79bcSJed Brown Input Parameters: 3999228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 4000228d79bcSJed Brown . iter - iteration number 4001228d79bcSJed Brown - rnorm - relative norm of the residual 4002228d79bcSJed Brown 4003228d79bcSJed Brown Notes: 4004228d79bcSJed Brown This routine is called by the SNES implementations. 4005228d79bcSJed Brown It does not typically need to be called by the user. 4006228d79bcSJed Brown 4007228d79bcSJed Brown Level: developer 4008228d79bcSJed Brown 4009228d79bcSJed Brown .seealso: SNESMonitorSet() 4010228d79bcSJed Brown @*/ 40117a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 40127a03ce2fSLisandro Dalcin { 40137a03ce2fSLisandro Dalcin PetscErrorCode ierr; 40147a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 40157a03ce2fSLisandro Dalcin 40167a03ce2fSLisandro Dalcin PetscFunctionBegin; 40178860a134SJunchao Zhang ierr = VecLockReadPush(snes->vec_sol);CHKERRQ(ierr); 40187a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 40197a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 40207a03ce2fSLisandro Dalcin } 40218860a134SJunchao Zhang ierr = VecLockReadPop(snes->vec_sol);CHKERRQ(ierr); 40227a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 40237a03ce2fSLisandro Dalcin } 40247a03ce2fSLisandro Dalcin 40259b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 40269b94acceSBarry Smith 4027bf388a1fSBarry Smith /*MC 4028bf388a1fSBarry Smith SNESMonitorFunction - functional form passed to SNESMonitorSet() to monitor convergence of nonlinear solver 4029bf388a1fSBarry Smith 4030bf388a1fSBarry Smith Synopsis: 4031aaa7dc30SBarry Smith #include <petscsnes.h> 4032bf388a1fSBarry Smith $ PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx) 4033bf388a1fSBarry Smith 40341843f636SBarry Smith Collective on snes 40351843f636SBarry Smith 40361843f636SBarry Smith Input Parameters: 4037bf388a1fSBarry Smith + snes - the SNES context 4038bf388a1fSBarry Smith . its - iteration number 4039bf388a1fSBarry Smith . norm - 2-norm function value (may be estimated) 4040bf388a1fSBarry Smith - mctx - [optional] monitoring context 4041bf388a1fSBarry Smith 4042878cb397SSatish Balay Level: advanced 4043878cb397SSatish Balay 4044bf388a1fSBarry Smith .seealso: SNESMonitorSet(), SNESMonitorGet() 4045bf388a1fSBarry Smith M*/ 4046bf388a1fSBarry Smith 40479b94acceSBarry Smith /*@C 4048a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 40499b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 40509b94acceSBarry Smith progress. 40519b94acceSBarry Smith 40523f9fe445SBarry Smith Logically Collective on SNES 4053fee21e36SBarry Smith 4054c7afd0dbSLois Curfman McInnes Input Parameters: 4055c7afd0dbSLois Curfman McInnes + snes - the SNES context 40566e4dcb14SBarry Smith . f - the monitor function, see SNESMonitorFunction for the calling sequence 4057b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 40580298fd71SBarry Smith monitor routine (use NULL if no context is desired) 4059b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 40600298fd71SBarry Smith (may be NULL) 40619b94acceSBarry Smith 40629665c990SLois Curfman McInnes Options Database Keys: 4063a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 4064798534f6SMatthew G. Knepley . -snes_monitor draw::draw_lg - sets line graph monitor, 4065cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 4066c7afd0dbSLois Curfman McInnes been hardwired into a code by 4067a6570f20SBarry Smith calls to SNESMonitorSet(), but 4068c7afd0dbSLois Curfman McInnes does not cancel those set via 4069c7afd0dbSLois Curfman McInnes the options database. 40709665c990SLois Curfman McInnes 4071639f9d9dSBarry Smith Notes: 40726bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 4073a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 40746bc08f3fSLois Curfman McInnes order in which they were set. 4075639f9d9dSBarry Smith 407695452b02SPatrick Sanan Fortran Notes: 407795452b02SPatrick Sanan Only a single monitor function can be set for each SNES object 4078025f1a04SBarry Smith 407936851e7fSLois Curfman McInnes Level: intermediate 408036851e7fSLois Curfman McInnes 4081bf388a1fSBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel(), SNESMonitorFunction 40829b94acceSBarry Smith @*/ 40836e4dcb14SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*f)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 40849b94acceSBarry Smith { 4085b90d0a6eSBarry Smith PetscInt i; 4086649052a6SBarry Smith PetscErrorCode ierr; 408778064530SBarry Smith PetscBool identical; 4088b90d0a6eSBarry Smith 40893a40ed3dSBarry Smith PetscFunctionBegin; 40900700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4091b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 409278064530SBarry Smith ierr = PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))snes->monitor[i],snes->monitorcontext[i],snes->monitordestroy[i],&identical);CHKERRQ(ierr); 409378064530SBarry Smith if (identical) PetscFunctionReturn(0); 4094649052a6SBarry Smith } 409578064530SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 40966e4dcb14SBarry Smith snes->monitor[snes->numbermonitors] = f; 4097b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 4098639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 40993a40ed3dSBarry Smith PetscFunctionReturn(0); 41009b94acceSBarry Smith } 41019b94acceSBarry Smith 4102a278d85bSSatish Balay /*@ 4103a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 41045cd90555SBarry Smith 41053f9fe445SBarry Smith Logically Collective on SNES 4106c7afd0dbSLois Curfman McInnes 41075cd90555SBarry Smith Input Parameters: 41085cd90555SBarry Smith . snes - the SNES context 41095cd90555SBarry Smith 41101a480d89SAdministrator Options Database Key: 4111a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 4112a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 4113c7afd0dbSLois Curfman McInnes set via the options database 41145cd90555SBarry Smith 41155cd90555SBarry Smith Notes: 41165cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 41175cd90555SBarry Smith 411836851e7fSLois Curfman McInnes Level: intermediate 411936851e7fSLois Curfman McInnes 4120a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 41215cd90555SBarry Smith @*/ 41227087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 41235cd90555SBarry Smith { 4124d952e501SBarry Smith PetscErrorCode ierr; 4125d952e501SBarry Smith PetscInt i; 4126d952e501SBarry Smith 41275cd90555SBarry Smith PetscFunctionBegin; 41280700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4129d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 4130d952e501SBarry Smith if (snes->monitordestroy[i]) { 41313c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 4132d952e501SBarry Smith } 4133d952e501SBarry Smith } 41345cd90555SBarry Smith snes->numbermonitors = 0; 41355cd90555SBarry Smith PetscFunctionReturn(0); 41365cd90555SBarry Smith } 41375cd90555SBarry Smith 4138bf388a1fSBarry Smith /*MC 4139bf388a1fSBarry Smith SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver 4140bf388a1fSBarry Smith 4141bf388a1fSBarry Smith Synopsis: 4142aaa7dc30SBarry Smith #include <petscsnes.h> 4143bf388a1fSBarry Smith $ PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 4144bf388a1fSBarry Smith 41451843f636SBarry Smith Collective on snes 41461843f636SBarry Smith 41471843f636SBarry Smith Input Parameters: 4148bf388a1fSBarry Smith + snes - the SNES context 4149bf388a1fSBarry Smith . it - current iteration (0 is the first and is before any Newton step) 4150bf388a1fSBarry Smith . xnorm - 2-norm of current iterate 4151bf388a1fSBarry Smith . gnorm - 2-norm of current step 41521843f636SBarry Smith . f - 2-norm of function 41531843f636SBarry Smith - cctx - [optional] convergence context 41541843f636SBarry Smith 41551843f636SBarry Smith Output Parameter: 41561843f636SBarry Smith . reason - reason for convergence/divergence, only needs to be set when convergence or divergence is detected 4157bf388a1fSBarry Smith 4158878cb397SSatish Balay Level: intermediate 4159bf388a1fSBarry Smith 4160bf388a1fSBarry Smith .seealso: SNESSetConvergenceTest(), SNESGetConvergenceTest() 4161bf388a1fSBarry Smith M*/ 4162bf388a1fSBarry Smith 41639b94acceSBarry Smith /*@C 41649b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 41659b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 41669b94acceSBarry Smith 41673f9fe445SBarry Smith Logically Collective on SNES 4168fee21e36SBarry Smith 4169c7afd0dbSLois Curfman McInnes Input Parameters: 4170c7afd0dbSLois Curfman McInnes + snes - the SNES context 4171bf388a1fSBarry Smith . SNESConvergenceTestFunction - routine to test for convergence 41720298fd71SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be NULL) 4173cf90aa19SBarry Smith - destroy - [optional] destructor for the context (may be NULL; PETSC_NULL_FUNCTION in Fortran) 41749b94acceSBarry Smith 417536851e7fSLois Curfman McInnes Level: advanced 417636851e7fSLois Curfman McInnes 4177e2a6519dSDmitry Karpeev .seealso: SNESConvergedDefault(), SNESConvergedSkip(), SNESConvergenceTestFunction 41789b94acceSBarry Smith @*/ 4179bf388a1fSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 41809b94acceSBarry Smith { 41817f7931b9SBarry Smith PetscErrorCode ierr; 41827f7931b9SBarry Smith 41833a40ed3dSBarry Smith PetscFunctionBegin; 41840700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4185e2a6519dSDmitry Karpeev if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip; 41867f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 41877f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 41887f7931b9SBarry Smith } 4189bf388a1fSBarry Smith snes->ops->converged = SNESConvergenceTestFunction; 41907f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 419185385478SLisandro Dalcin snes->cnvP = cctx; 41923a40ed3dSBarry Smith PetscFunctionReturn(0); 41939b94acceSBarry Smith } 41949b94acceSBarry Smith 419552baeb72SSatish Balay /*@ 4196184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 4197184914b5SBarry Smith 4198184914b5SBarry Smith Not Collective 4199184914b5SBarry Smith 4200184914b5SBarry Smith Input Parameter: 4201184914b5SBarry Smith . snes - the SNES context 4202184914b5SBarry Smith 4203184914b5SBarry Smith Output Parameter: 42044d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 4205184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 4206184914b5SBarry Smith 42076a4d7782SBarry Smith Options Database: 42086a4d7782SBarry Smith . -snes_converged_reason - prints the reason to standard out 42096a4d7782SBarry Smith 4210184914b5SBarry Smith Level: intermediate 4211184914b5SBarry Smith 421295452b02SPatrick Sanan Notes: 421395452b02SPatrick Sanan Should only be called after the call the SNESSolve() is complete, if it is called earlier it returns the value SNES__CONVERGED_ITERATING. 4214184914b5SBarry Smith 421533866048SMatthew G. Knepley .seealso: SNESSetConvergenceTest(), SNESSetConvergedReason(), SNESConvergedReason 4216184914b5SBarry Smith @*/ 42177087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 4218184914b5SBarry Smith { 4219184914b5SBarry Smith PetscFunctionBegin; 42200700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 42214482741eSBarry Smith PetscValidPointer(reason,2); 4222184914b5SBarry Smith *reason = snes->reason; 4223184914b5SBarry Smith PetscFunctionReturn(0); 4224184914b5SBarry Smith } 4225184914b5SBarry Smith 4226c4421ceaSFande Kong /*@C 4227c4421ceaSFande Kong SNESGetConvergedReasonString - Return a human readable string for snes converged reason 4228c4421ceaSFande Kong 4229c4421ceaSFande Kong Not Collective 4230c4421ceaSFande Kong 4231c4421ceaSFande Kong Input Parameter: 4232c4421ceaSFande Kong . snes - the SNES context 4233c4421ceaSFande Kong 4234c4421ceaSFande Kong Output Parameter: 4235c4421ceaSFande Kong . strreason - a human readable string that describes SNES converged reason 4236c4421ceaSFande Kong 423799c90e12SSatish Balay Level: beginner 4238c4421ceaSFande Kong 4239c4421ceaSFande Kong .seealso: SNESGetConvergedReason() 4240c4421ceaSFande Kong @*/ 4241c4421ceaSFande Kong PetscErrorCode SNESGetConvergedReasonString(SNES snes, const char** strreason) 4242c4421ceaSFande Kong { 4243c4421ceaSFande Kong PetscFunctionBegin; 4244c4421ceaSFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4245c4421ceaSFande Kong PetscValidCharPointer(strreason,2); 4246c4421ceaSFande Kong *strreason = SNESConvergedReasons[snes->reason]; 4247c4421ceaSFande Kong PetscFunctionReturn(0); 4248c4421ceaSFande Kong } 4249c4421ceaSFande Kong 425033866048SMatthew G. Knepley /*@ 425133866048SMatthew G. Knepley SNESSetConvergedReason - Sets the reason the SNES iteration was stopped. 425233866048SMatthew G. Knepley 425333866048SMatthew G. Knepley Not Collective 425433866048SMatthew G. Knepley 425533866048SMatthew G. Knepley Input Parameters: 425633866048SMatthew G. Knepley + snes - the SNES context 425733866048SMatthew G. Knepley - reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 425833866048SMatthew G. Knepley manual pages for the individual convergence tests for complete lists 425933866048SMatthew G. Knepley 426033866048SMatthew G. Knepley Level: intermediate 426133866048SMatthew G. Knepley 426233866048SMatthew G. Knepley .seealso: SNESGetConvergedReason(), SNESSetConvergenceTest(), SNESConvergedReason 426333866048SMatthew G. Knepley @*/ 426433866048SMatthew G. Knepley PetscErrorCode SNESSetConvergedReason(SNES snes,SNESConvergedReason reason) 426533866048SMatthew G. Knepley { 426633866048SMatthew G. Knepley PetscFunctionBegin; 426733866048SMatthew G. Knepley PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 426833866048SMatthew G. Knepley snes->reason = reason; 426933866048SMatthew G. Knepley PetscFunctionReturn(0); 427033866048SMatthew G. Knepley } 427133866048SMatthew G. Knepley 4272c9005455SLois Curfman McInnes /*@ 4273c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 4274c9005455SLois Curfman McInnes 42753f9fe445SBarry Smith Logically Collective on SNES 4276fee21e36SBarry Smith 4277c7afd0dbSLois Curfman McInnes Input Parameters: 4278c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 42798c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 4280cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 4281758f92a0SBarry Smith . na - size of a and its 428264731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 4283758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 4284c7afd0dbSLois Curfman McInnes 4285308dcc3eSBarry Smith Notes: 42860298fd71SBarry Smith If 'a' and 'its' are NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 4287308dcc3eSBarry Smith default array of length 10000 is allocated. 4288308dcc3eSBarry Smith 4289c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 4290c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 4291c9005455SLois Curfman McInnes during the section of code that is being timed. 4292c9005455SLois Curfman McInnes 429336851e7fSLois Curfman McInnes Level: intermediate 429436851e7fSLois Curfman McInnes 429508405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 4296758f92a0SBarry Smith 4297c9005455SLois Curfman McInnes @*/ 42987087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 4299c9005455SLois Curfman McInnes { 4300308dcc3eSBarry Smith PetscErrorCode ierr; 4301308dcc3eSBarry Smith 43023a40ed3dSBarry Smith PetscFunctionBegin; 43030700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4304064a246eSJacob Faibussowitsch if (a) PetscValidRealPointer(a,2); 4305a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 43067a1ec6d4SBarry Smith if (!a) { 4307308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 4308071fcb05SBarry Smith ierr = PetscCalloc2(na,&a,na,&its);CHKERRQ(ierr); 4309071fcb05SBarry Smith snes->conv_hist_alloc = PETSC_TRUE; 4310308dcc3eSBarry Smith } 4311c9005455SLois Curfman McInnes snes->conv_hist = a; 4312758f92a0SBarry Smith snes->conv_hist_its = its; 4313758f92a0SBarry Smith snes->conv_hist_max = na; 4314a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 4315758f92a0SBarry Smith snes->conv_hist_reset = reset; 4316758f92a0SBarry Smith PetscFunctionReturn(0); 4317758f92a0SBarry Smith } 4318758f92a0SBarry Smith 4319308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4320c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 4321c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 432299e0435eSBarry Smith 43238cc058d9SJed Brown PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 4324308dcc3eSBarry Smith { 4325308dcc3eSBarry Smith mxArray *mat; 4326308dcc3eSBarry Smith PetscInt i; 4327308dcc3eSBarry Smith PetscReal *ar; 4328308dcc3eSBarry Smith 4329308dcc3eSBarry Smith PetscFunctionBegin; 4330308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 4331308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 4332f5af7f23SKarl Rupp for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i]; 4333308dcc3eSBarry Smith PetscFunctionReturn(mat); 4334308dcc3eSBarry Smith } 4335308dcc3eSBarry Smith #endif 4336308dcc3eSBarry Smith 43370c4c9dddSBarry Smith /*@C 4338758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 4339758f92a0SBarry Smith 43403f9fe445SBarry Smith Not Collective 4341758f92a0SBarry Smith 4342758f92a0SBarry Smith Input Parameter: 4343758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 4344758f92a0SBarry Smith 4345758f92a0SBarry Smith Output Parameters: 4346a2b725a8SWilliam Gropp + a - array to hold history 4347758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 4348758f92a0SBarry Smith negative if not converged) for each solve. 4349758f92a0SBarry Smith - na - size of a and its 4350758f92a0SBarry Smith 4351758f92a0SBarry Smith Notes: 4352758f92a0SBarry Smith The calling sequence for this routine in Fortran is 4353758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 4354758f92a0SBarry Smith 4355758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 4356758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 4357758f92a0SBarry Smith during the section of code that is being timed. 4358758f92a0SBarry Smith 4359758f92a0SBarry Smith Level: intermediate 4360758f92a0SBarry Smith 43615ea7661aSPierre Jolivet .seealso: SNESSetConvergenceHistory() 4362758f92a0SBarry Smith 4363758f92a0SBarry Smith @*/ 43647087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 4365758f92a0SBarry Smith { 4366758f92a0SBarry Smith PetscFunctionBegin; 43670700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4368758f92a0SBarry Smith if (a) *a = snes->conv_hist; 4369758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 4370758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 43713a40ed3dSBarry Smith PetscFunctionReturn(0); 4372c9005455SLois Curfman McInnes } 4373c9005455SLois Curfman McInnes 4374ac226902SBarry Smith /*@C 437576b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 4376eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 43777e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 437876b2cf59SMatthew Knepley 43793f9fe445SBarry Smith Logically Collective on SNES 438076b2cf59SMatthew Knepley 438176b2cf59SMatthew Knepley Input Parameters: 4382a2b725a8SWilliam Gropp + snes - The nonlinear solver context 4383a2b725a8SWilliam Gropp - func - The function 438476b2cf59SMatthew Knepley 438576b2cf59SMatthew Knepley Calling sequence of func: 4386a2b725a8SWilliam Gropp $ func (SNES snes, PetscInt step); 438776b2cf59SMatthew Knepley 438876b2cf59SMatthew Knepley . step - The current step of the iteration 438976b2cf59SMatthew Knepley 4390fe97e370SBarry Smith Level: advanced 4391fe97e370SBarry Smith 43926b7fb656SBarry Smith Note: 43936b7fb656SBarry Smith 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() 4394fe97e370SBarry Smith This is not used by most users. 439576b2cf59SMatthew Knepley 43966b7fb656SBarry Smith There are a varity of function hooks one many set that are called at different stages of the nonlinear solution process, see the functions listed below. 43976b7fb656SBarry Smith 43986b7fb656SBarry Smith .seealso SNESSetJacobian(), SNESSolve(), SNESLineSearchSetPreCheck(), SNESLineSearchSetPostCheck(), SNESNewtonTRSetPreCheck(), SNESNewtonTRSetPostCheck(), 43996b7fb656SBarry Smith SNESMonitorSet(), SNESSetDivergenceTest() 440076b2cf59SMatthew Knepley @*/ 44017087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 440276b2cf59SMatthew Knepley { 440376b2cf59SMatthew Knepley PetscFunctionBegin; 44040700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 4405e7788613SBarry Smith snes->ops->update = func; 440676b2cf59SMatthew Knepley PetscFunctionReturn(0); 440776b2cf59SMatthew Knepley } 440876b2cf59SMatthew Knepley 44099b94acceSBarry Smith /* 44109b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 44119b94acceSBarry Smith positive parameter delta. 44129b94acceSBarry Smith 44139b94acceSBarry Smith Input Parameters: 4414c7afd0dbSLois Curfman McInnes + snes - the SNES context 44159b94acceSBarry Smith . y - approximate solution of linear system 44169b94acceSBarry Smith . fnorm - 2-norm of current function 4417c7afd0dbSLois Curfman McInnes - delta - trust region size 44189b94acceSBarry Smith 44199b94acceSBarry Smith Output Parameters: 4420c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 44219b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 44229b94acceSBarry Smith region, and exceeds zero otherwise. 4423c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 44249b94acceSBarry Smith 44259b94acceSBarry Smith Note: 442604d7464bSBarry Smith For non-trust region methods such as SNESNEWTONLS, the parameter delta 44279b94acceSBarry Smith is set to be the maximum allowable step size. 44289b94acceSBarry Smith 44299b94acceSBarry Smith */ 4430dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 44319b94acceSBarry Smith { 4432064f8208SBarry Smith PetscReal nrm; 4433ea709b57SSatish Balay PetscScalar cnorm; 4434dfbe8321SBarry Smith PetscErrorCode ierr; 44353a40ed3dSBarry Smith 44363a40ed3dSBarry Smith PetscFunctionBegin; 44370700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 44380700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 4439c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 4440184914b5SBarry Smith 4441064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 4442064f8208SBarry Smith if (nrm > *delta) { 4443064f8208SBarry Smith nrm = *delta/nrm; 4444064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 4445064f8208SBarry Smith cnorm = nrm; 44462dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 44479b94acceSBarry Smith *ynorm = *delta; 44489b94acceSBarry Smith } else { 44499b94acceSBarry Smith *gpnorm = 0.0; 4450064f8208SBarry Smith *ynorm = nrm; 44519b94acceSBarry Smith } 44523a40ed3dSBarry Smith PetscFunctionReturn(0); 44539b94acceSBarry Smith } 44549b94acceSBarry Smith 445591f3e32bSBarry Smith /*@C 445619a666eeSBarry Smith SNESConvergedReasonView - Displays the reason a SNES solve converged or diverged to a viewer 44572a359c20SBarry Smith 44582a359c20SBarry Smith Collective on SNES 44592a359c20SBarry Smith 44602a359c20SBarry Smith Parameter: 44612a359c20SBarry Smith + snes - iterative context obtained from SNESCreate() 44622a359c20SBarry Smith - viewer - the viewer to display the reason 44632a359c20SBarry Smith 44642a359c20SBarry Smith Options Database Keys: 4465ee300463SSatish Balay + -snes_converged_reason - print reason for converged or diverged, also prints number of iterations 4466ee300463SSatish Balay - -snes_converged_reason ::failed - only print reason and number of iterations when diverged 4467eafd5ff0SAlex Lindsay 446819a666eeSBarry Smith Notes: 446919a666eeSBarry Smith To change the format of the output call PetscViewerPushFormat(viewer,format) before this call. Use PETSC_VIEWER_DEFAULT for the default, 447019a666eeSBarry Smith use PETSC_VIEWER_FAILED to only display a reason if it fails. 44712a359c20SBarry Smith 44722a359c20SBarry Smith Level: beginner 44732a359c20SBarry Smith 447419a666eeSBarry Smith .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault(), SNESGetConvergedReason(), SNESConvergedReasonViewFromOptions(), 447519a666eeSBarry Smith PetscViewerPushFormat(), PetscViewerPopFormat() 44762a359c20SBarry Smith 44772a359c20SBarry Smith @*/ 447819a666eeSBarry Smith PetscErrorCode SNESConvergedReasonView(SNES snes,PetscViewer viewer) 44792a359c20SBarry Smith { 448075cca76cSMatthew G. Knepley PetscViewerFormat format; 44812a359c20SBarry Smith PetscBool isAscii; 448275cca76cSMatthew G. Knepley PetscErrorCode ierr; 44832a359c20SBarry Smith 44842a359c20SBarry Smith PetscFunctionBegin; 448519a666eeSBarry Smith if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 44862a359c20SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);CHKERRQ(ierr); 44872a359c20SBarry Smith if (isAscii) { 448875cca76cSMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 44892a359c20SBarry Smith ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 449075cca76cSMatthew G. Knepley if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 449175cca76cSMatthew G. Knepley DM dm; 449275cca76cSMatthew G. Knepley Vec u; 449375cca76cSMatthew G. Knepley PetscDS prob; 449475cca76cSMatthew G. Knepley PetscInt Nf, f; 449595cbbfd3SMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 449695cbbfd3SMatthew G. Knepley void **exactCtx; 449775cca76cSMatthew G. Knepley PetscReal error; 449875cca76cSMatthew G. Knepley 449975cca76cSMatthew G. Knepley ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 450075cca76cSMatthew G. Knepley ierr = SNESGetSolution(snes, &u);CHKERRQ(ierr); 450175cca76cSMatthew G. Knepley ierr = DMGetDS(dm, &prob);CHKERRQ(ierr); 450275cca76cSMatthew G. Knepley ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 450395cbbfd3SMatthew G. Knepley ierr = PetscMalloc2(Nf, &exactSol, Nf, &exactCtx);CHKERRQ(ierr); 450495cbbfd3SMatthew G. Knepley for (f = 0; f < Nf; ++f) {ierr = PetscDSGetExactSolution(prob, f, &exactSol[f], &exactCtx[f]);CHKERRQ(ierr);} 450595cbbfd3SMatthew G. Knepley ierr = DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error);CHKERRQ(ierr); 450695cbbfd3SMatthew G. Knepley ierr = PetscFree2(exactSol, exactCtx);CHKERRQ(ierr); 450775cca76cSMatthew G. Knepley if (error < 1.0e-11) {ierr = PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n");CHKERRQ(ierr);} 450875cca76cSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", error);CHKERRQ(ierr);} 450975cca76cSMatthew G. Knepley } 4510eafd5ff0SAlex Lindsay if (snes->reason > 0 && format != PETSC_VIEWER_FAILED) { 45112a359c20SBarry Smith if (((PetscObject) snes)->prefix) { 45122a359c20SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve converged due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 45132a359c20SBarry Smith } else { 45142a359c20SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 45152a359c20SBarry Smith } 4516eafd5ff0SAlex Lindsay } else if (snes->reason <= 0) { 45172a359c20SBarry Smith if (((PetscObject) snes)->prefix) { 45182a359c20SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve did not converge due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 45192a359c20SBarry Smith } else { 45202a359c20SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 45212a359c20SBarry Smith } 45222a359c20SBarry Smith } 45232a359c20SBarry Smith ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 45242a359c20SBarry Smith } 45252a359c20SBarry Smith PetscFunctionReturn(0); 45262a359c20SBarry Smith } 45272a359c20SBarry Smith 4528c4421ceaSFande Kong /*@C 4529c4421ceaSFande Kong SNESConvergedReasonViewSet - Sets an ADDITIONAL function that is to be used at the 4530c4421ceaSFande Kong end of the nonlinear solver to display the conver reason of the nonlinear solver. 4531c4421ceaSFande Kong 4532c4421ceaSFande Kong Logically Collective on SNES 4533c4421ceaSFande Kong 4534c4421ceaSFande Kong Input Parameters: 4535c4421ceaSFande Kong + snes - the SNES context 4536c4421ceaSFande Kong . f - the snes converged reason view function 4537c4421ceaSFande Kong . vctx - [optional] user-defined context for private data for the 4538c4421ceaSFande Kong snes converged reason view routine (use NULL if no context is desired) 4539c4421ceaSFande Kong - reasonviewdestroy - [optional] routine that frees reasonview context 4540c4421ceaSFande Kong (may be NULL) 4541c4421ceaSFande Kong 4542c4421ceaSFande Kong Options Database Keys: 4543c4421ceaSFande Kong + -snes_converged_reason - sets a default SNESConvergedReasonView() 4544c4421ceaSFande Kong - -snes_converged_reason_view_cancel - cancels all converged reason viewers that have 4545c4421ceaSFande Kong been hardwired into a code by 4546c4421ceaSFande Kong calls to SNESConvergedReasonViewSet(), but 4547c4421ceaSFande Kong does not cancel those set via 4548c4421ceaSFande Kong the options database. 4549c4421ceaSFande Kong 4550c4421ceaSFande Kong Notes: 4551c4421ceaSFande Kong Several different converged reason view routines may be set by calling 4552c4421ceaSFande Kong SNESConvergedReasonViewSet() multiple times; all will be called in the 4553c4421ceaSFande Kong order in which they were set. 4554c4421ceaSFande Kong 4555c4421ceaSFande Kong Level: intermediate 4556c4421ceaSFande Kong 4557c4421ceaSFande Kong .seealso: SNESConvergedReasonView(), SNESConvergedReasonViewCancel() 4558c4421ceaSFande Kong @*/ 4559c4421ceaSFande Kong PetscErrorCode SNESConvergedReasonViewSet(SNES snes,PetscErrorCode (*f)(SNES,void*),void *vctx,PetscErrorCode (*reasonviewdestroy)(void**)) 4560c4421ceaSFande Kong { 4561c4421ceaSFande Kong PetscInt i; 4562c4421ceaSFande Kong PetscErrorCode ierr; 4563c4421ceaSFande Kong PetscBool identical; 4564c4421ceaSFande Kong 4565c4421ceaSFande Kong PetscFunctionBegin; 4566c4421ceaSFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4567c4421ceaSFande Kong for (i=0; i<snes->numberreasonviews;i++) { 4568c4421ceaSFande Kong ierr = PetscMonitorCompare((PetscErrorCode (*)(void))f,vctx,reasonviewdestroy,(PetscErrorCode (*)(void))snes->reasonview[i],snes->reasonviewcontext[i],snes->reasonviewdestroy[i],&identical);CHKERRQ(ierr); 4569c4421ceaSFande Kong if (identical) PetscFunctionReturn(0); 4570c4421ceaSFande Kong } 4571c4421ceaSFande Kong if (snes->numberreasonviews >= MAXSNESREASONVIEWS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many SNES reasonview set"); 4572c4421ceaSFande Kong snes->reasonview[snes->numberreasonviews] = f; 4573c4421ceaSFande Kong snes->reasonviewdestroy[snes->numberreasonviews] = reasonviewdestroy; 4574c4421ceaSFande Kong snes->reasonviewcontext[snes->numberreasonviews++] = (void*)vctx; 4575c4421ceaSFande Kong PetscFunctionReturn(0); 4576c4421ceaSFande Kong } 4577c4421ceaSFande Kong 457891f3e32bSBarry Smith /*@ 457919a666eeSBarry Smith SNESConvergedReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed. 4580c4421ceaSFande Kong All the user-provided convergedReasonView routines will be involved as well, if they exist. 45812a359c20SBarry Smith 45822a359c20SBarry Smith Collective on SNES 45832a359c20SBarry Smith 45842a359c20SBarry Smith Input Parameters: 45852a359c20SBarry Smith . snes - the SNES object 45862a359c20SBarry Smith 45872a359c20SBarry Smith Level: intermediate 45882a359c20SBarry Smith 458919a666eeSBarry Smith .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault(), SNESGetConvergedReason(), SNESConvergedReasonView() 459019a666eeSBarry Smith 45912a359c20SBarry Smith @*/ 459219a666eeSBarry Smith PetscErrorCode SNESConvergedReasonViewFromOptions(SNES snes) 45932a359c20SBarry Smith { 45942a359c20SBarry Smith PetscErrorCode ierr; 45952a359c20SBarry Smith PetscViewer viewer; 45962a359c20SBarry Smith PetscBool flg; 45972a359c20SBarry Smith static PetscBool incall = PETSC_FALSE; 45982a359c20SBarry Smith PetscViewerFormat format; 4599c4421ceaSFande Kong PetscInt i; 46002a359c20SBarry Smith 46012a359c20SBarry Smith PetscFunctionBegin; 46022a359c20SBarry Smith if (incall) PetscFunctionReturn(0); 46032a359c20SBarry Smith incall = PETSC_TRUE; 4604c4421ceaSFande Kong 4605c4421ceaSFande Kong /* All user-provided viewers are called first, if they exist. */ 4606c4421ceaSFande Kong for (i=0; i<snes->numberreasonviews; i++) { 4607c4421ceaSFande Kong ierr = (*snes->reasonview[i])(snes,snes->reasonviewcontext[i]);CHKERRQ(ierr); 4608c4421ceaSFande Kong } 4609c4421ceaSFande Kong 4610c4421ceaSFande Kong /* Call PETSc default routine if users ask for it */ 461116413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_converged_reason",&viewer,&format,&flg);CHKERRQ(ierr); 46122a359c20SBarry Smith if (flg) { 46132a359c20SBarry Smith ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 461419a666eeSBarry Smith ierr = SNESConvergedReasonView(snes,viewer);CHKERRQ(ierr); 46152a359c20SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 46162a359c20SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 46172a359c20SBarry Smith } 46182a359c20SBarry Smith incall = PETSC_FALSE; 46192a359c20SBarry Smith PetscFunctionReturn(0); 46202a359c20SBarry Smith } 46212a359c20SBarry Smith 4622487a658cSBarry Smith /*@ 4623f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 4624f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 46259b94acceSBarry Smith 4626c7afd0dbSLois Curfman McInnes Collective on SNES 4627c7afd0dbSLois Curfman McInnes 4628b2002411SLois Curfman McInnes Input Parameters: 4629c7afd0dbSLois Curfman McInnes + snes - the SNES context 46300298fd71SBarry Smith . b - the constant part of the equation F(x) = b, or NULL to use zero. 463185385478SLisandro Dalcin - x - the solution vector. 46329b94acceSBarry Smith 4633b2002411SLois Curfman McInnes Notes: 46348ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 46356b7fb656SBarry Smith for the nonlinear solve prior to calling SNESSolve(). In particular, 46368ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 46378ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 46388ddd3da0SLois Curfman McInnes 463936851e7fSLois Curfman McInnes Level: beginner 464036851e7fSLois Curfman McInnes 46416b7fb656SBarry Smith .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution(), 46426b7fb656SBarry Smith SNESNewtonTRSetPreCheck(), SNESNewtonTRGetPreCheck(), SNESNewtonTRSetPostCheck(), SNESNewtonTRGetPostCheck(), 46436b7fb656SBarry Smith SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck() 46449b94acceSBarry Smith @*/ 46457087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 46469b94acceSBarry Smith { 4647dfbe8321SBarry Smith PetscErrorCode ierr; 4648ace3abfcSBarry Smith PetscBool flg; 4649efd51863SBarry Smith PetscInt grid; 46500298fd71SBarry Smith Vec xcreated = NULL; 4651caa4e7f2SJed Brown DM dm; 4652052efed2SBarry Smith 46533a40ed3dSBarry Smith PetscFunctionBegin; 46540700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4655a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 4656a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 46570700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 465885385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 465985385478SLisandro Dalcin 466034b4d3a8SMatthew G. Knepley /* High level operations using the nonlinear solver */ 466106fc46c8SMatthew G. Knepley { 466206fc46c8SMatthew G. Knepley PetscViewer viewer; 466306fc46c8SMatthew G. Knepley PetscViewerFormat format; 46647c88af5aSMatthew G. Knepley PetscInt num; 466506fc46c8SMatthew G. Knepley PetscBool flg; 466606fc46c8SMatthew G. Knepley static PetscBool incall = PETSC_FALSE; 466706fc46c8SMatthew G. Knepley 466806fc46c8SMatthew G. Knepley if (!incall) { 466934b4d3a8SMatthew G. Knepley /* Estimate the convergence rate of the discretization */ 467016413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) snes),((PetscObject)snes)->options, ((PetscObject) snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg);CHKERRQ(ierr); 467106fc46c8SMatthew G. Knepley if (flg) { 467206fc46c8SMatthew G. Knepley PetscConvEst conv; 467346079b62SMatthew G. Knepley DM dm; 467446079b62SMatthew G. Knepley PetscReal *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */ 467546079b62SMatthew G. Knepley PetscInt Nf; 467606fc46c8SMatthew G. Knepley 467706fc46c8SMatthew G. Knepley incall = PETSC_TRUE; 467846079b62SMatthew G. Knepley ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 467946079b62SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 4680ca5a3622SMatthew G. Knepley ierr = PetscCalloc1(Nf, &alpha);CHKERRQ(ierr); 468106fc46c8SMatthew G. Knepley ierr = PetscConvEstCreate(PetscObjectComm((PetscObject) snes), &conv);CHKERRQ(ierr); 4682900f6b5bSMatthew G. Knepley ierr = PetscConvEstSetSolver(conv, (PetscObject) snes);CHKERRQ(ierr); 468306fc46c8SMatthew G. Knepley ierr = PetscConvEstSetFromOptions(conv);CHKERRQ(ierr); 46840955ed61SMatthew G. Knepley ierr = PetscConvEstSetUp(conv);CHKERRQ(ierr); 468546079b62SMatthew G. Knepley ierr = PetscConvEstGetConvRate(conv, alpha);CHKERRQ(ierr); 468606fc46c8SMatthew G. Knepley ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr); 468706fc46c8SMatthew G. Knepley ierr = PetscConvEstRateView(conv, alpha, viewer);CHKERRQ(ierr); 468806fc46c8SMatthew G. Knepley ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 468906fc46c8SMatthew G. Knepley ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 469006fc46c8SMatthew G. Knepley ierr = PetscConvEstDestroy(&conv);CHKERRQ(ierr); 469146079b62SMatthew G. Knepley ierr = PetscFree(alpha);CHKERRQ(ierr); 469206fc46c8SMatthew G. Knepley incall = PETSC_FALSE; 469306fc46c8SMatthew G. Knepley } 469434b4d3a8SMatthew G. Knepley /* Adaptively refine the initial grid */ 4695b2588ea6SMatthew G. Knepley num = 1; 4696b2588ea6SMatthew G. Knepley ierr = PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_initial", &num, &flg);CHKERRQ(ierr); 469734b4d3a8SMatthew G. Knepley if (flg) { 469834b4d3a8SMatthew G. Knepley DMAdaptor adaptor; 469934b4d3a8SMatthew G. Knepley 470034b4d3a8SMatthew G. Knepley incall = PETSC_TRUE; 4701ea13f565SStefano Zampini ierr = DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor);CHKERRQ(ierr); 470234b4d3a8SMatthew G. Knepley ierr = DMAdaptorSetSolver(adaptor, snes);CHKERRQ(ierr); 4703b2588ea6SMatthew G. Knepley ierr = DMAdaptorSetSequenceLength(adaptor, num);CHKERRQ(ierr); 470434b4d3a8SMatthew G. Knepley ierr = DMAdaptorSetFromOptions(adaptor);CHKERRQ(ierr); 470534b4d3a8SMatthew G. Knepley ierr = DMAdaptorSetUp(adaptor);CHKERRQ(ierr); 470634b4d3a8SMatthew G. Knepley ierr = DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x);CHKERRQ(ierr); 470734b4d3a8SMatthew G. Knepley ierr = DMAdaptorDestroy(&adaptor);CHKERRQ(ierr); 470834b4d3a8SMatthew G. Knepley incall = PETSC_FALSE; 470934b4d3a8SMatthew G. Knepley } 47107c88af5aSMatthew G. Knepley /* Use grid sequencing to adapt */ 47117c88af5aSMatthew G. Knepley num = 0; 47127c88af5aSMatthew G. Knepley ierr = PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_sequence", &num, NULL);CHKERRQ(ierr); 47137c88af5aSMatthew G. Knepley if (num) { 47147c88af5aSMatthew G. Knepley DMAdaptor adaptor; 47157c88af5aSMatthew G. Knepley 47167c88af5aSMatthew G. Knepley incall = PETSC_TRUE; 4717ea13f565SStefano Zampini ierr = DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor);CHKERRQ(ierr); 47187c88af5aSMatthew G. Knepley ierr = DMAdaptorSetSolver(adaptor, snes);CHKERRQ(ierr); 47197c88af5aSMatthew G. Knepley ierr = DMAdaptorSetSequenceLength(adaptor, num);CHKERRQ(ierr); 47207c88af5aSMatthew G. Knepley ierr = DMAdaptorSetFromOptions(adaptor);CHKERRQ(ierr); 47217c88af5aSMatthew G. Knepley ierr = DMAdaptorSetUp(adaptor);CHKERRQ(ierr); 47227c88af5aSMatthew G. Knepley ierr = DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x);CHKERRQ(ierr); 47237c88af5aSMatthew G. Knepley ierr = DMAdaptorDestroy(&adaptor);CHKERRQ(ierr); 47247c88af5aSMatthew G. Knepley incall = PETSC_FALSE; 47257c88af5aSMatthew G. Knepley } 472606fc46c8SMatthew G. Knepley } 472706fc46c8SMatthew G. Knepley } 4728caa4e7f2SJed Brown if (!x) { 4729caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4730caa4e7f2SJed Brown ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 4731a69afd8bSBarry Smith x = xcreated; 4732a69afd8bSBarry Smith } 4733ce1779c8SBarry Smith ierr = SNESViewFromOptions(snes,NULL,"-snes_view_pre");CHKERRQ(ierr); 4734f05ece33SBarry Smith 4735ce94432eSBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);} 4736efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 4737efd51863SBarry Smith 473885385478SLisandro Dalcin /* set solution vector */ 4739efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 47406bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 474185385478SLisandro Dalcin snes->vec_sol = x; 4742caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4743caa4e7f2SJed Brown 4744caa4e7f2SJed Brown /* set affine vector if provided */ 474585385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 47466bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 474785385478SLisandro Dalcin snes->vec_rhs = b; 474885385478SLisandro Dalcin 4749bfdd6862SPatrick Farrell if (snes->vec_rhs && (snes->vec_func == snes->vec_rhs)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Right hand side vector cannot be function vector"); 4750154060b5SMatthew G. Knepley if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 4751154060b5SMatthew G. Knepley if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 4752154060b5SMatthew G. Knepley if (!snes->vec_sol_update /* && snes->vec_sol */) { 4753154060b5SMatthew G. Knepley ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 4754154060b5SMatthew G. Knepley ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update);CHKERRQ(ierr); 4755154060b5SMatthew G. Knepley } 4756154060b5SMatthew G. Knepley ierr = DMShellSetGlobalVector(dm,snes->vec_sol);CHKERRQ(ierr); 475770e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 47583f149594SLisandro Dalcin 47597eee914bSBarry Smith if (!grid) { 47607eee914bSBarry Smith if (snes->ops->computeinitialguess) { 4761d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 4762d25893d9SBarry Smith } 4763dd568438SSatish Balay } 4764d25893d9SBarry Smith 4765abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 4766971e163fSPeter Brune if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;} 4767d5e45103SBarry Smith 47683f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 47694936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 477085385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 477117186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 4772422a814eSBarry Smith snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */ 47733f149594SLisandro Dalcin 477437ec4e1aSPeter Brune if (snes->lagjac_persist) snes->jac_iter += snes->iter; 477537ec4e1aSPeter Brune if (snes->lagpre_persist) snes->pre_iter += snes->iter; 477637ec4e1aSPeter Brune 477716413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_test_local_min",NULL,NULL,&flg);CHKERRQ(ierr); 4778da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 4779c4421ceaSFande Kong /* Call converged reason views. This may involve user-provided viewers as well */ 478019a666eeSBarry Smith ierr = SNESConvergedReasonViewFromOptions(snes);CHKERRQ(ierr); 47815968eb51SBarry Smith 4782ce94432eSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 47839c8e83a9SBarry Smith if (snes->reason < 0) break; 4784efd51863SBarry Smith if (grid < snes->gridsequence) { 4785efd51863SBarry Smith DM fine; 4786efd51863SBarry Smith Vec xnew; 4787efd51863SBarry Smith Mat interp; 4788efd51863SBarry Smith 4789ce94432eSBarry Smith ierr = DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine);CHKERRQ(ierr); 4790ce94432eSBarry Smith if (!fine) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 47910298fd71SBarry Smith ierr = DMCreateInterpolation(snes->dm,fine,&interp,NULL);CHKERRQ(ierr); 4792efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 4793efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 4794c833c3b5SJed Brown ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr); 4795efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 4796efd51863SBarry Smith x = xnew; 4797efd51863SBarry Smith 4798efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 4799efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 4800352f405dSMatthew G. Knepley ierr = SNESResetFromOptions(snes);CHKERRQ(ierr); 4801efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 4802ce94432eSBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr); 4803efd51863SBarry Smith } 4804efd51863SBarry Smith } 4805ce1779c8SBarry Smith ierr = SNESViewFromOptions(snes,NULL,"-snes_view");CHKERRQ(ierr); 4806685405a1SBarry Smith ierr = VecViewFromOptions(snes->vec_sol,(PetscObject)snes,"-snes_view_solution");CHKERRQ(ierr); 4807c0f0dcc3SMatthew G. Knepley ierr = DMMonitor(snes->dm);CHKERRQ(ierr); 48083f7e2da0SPeter Brune 4809a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 4810e04113cfSBarry Smith ierr = PetscObjectSAWsBlock((PetscObject)snes);CHKERRQ(ierr); 48113a40ed3dSBarry Smith PetscFunctionReturn(0); 48129b94acceSBarry Smith } 48139b94acceSBarry Smith 48149b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 48159b94acceSBarry Smith 481682bf6240SBarry Smith /*@C 48174b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 48189b94acceSBarry Smith 4819fee21e36SBarry Smith Collective on SNES 4820fee21e36SBarry Smith 4821c7afd0dbSLois Curfman McInnes Input Parameters: 4822c7afd0dbSLois Curfman McInnes + snes - the SNES context 4823454a90a3SBarry Smith - type - a known method 4824c7afd0dbSLois Curfman McInnes 4825c7afd0dbSLois Curfman McInnes Options Database Key: 4826454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 482704d7464bSBarry Smith of available methods (for instance, newtonls or newtontr) 4828ae12b187SLois Curfman McInnes 48299b94acceSBarry Smith Notes: 4830e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 483104d7464bSBarry Smith + SNESNEWTONLS - Newton's method with line search 4832c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 4833a2b725a8SWilliam Gropp - SNESNEWTONTR - Newton's method with trust region 4834c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 48359b94acceSBarry Smith 4836ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 4837ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 4838ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 4839ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 4840ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 4841ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 4842ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 4843ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 4844ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 4845b0a32e0cSBarry Smith appropriate method. 484636851e7fSLois Curfman McInnes 484795452b02SPatrick Sanan Developer Notes: 484895452b02SPatrick Sanan SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates 48498f6c3df8SBarry Smith the constructor in that list and calls it to create the spexific object. 48508f6c3df8SBarry Smith 485136851e7fSLois Curfman McInnes Level: intermediate 4852a703fe33SLois Curfman McInnes 48538f6c3df8SBarry Smith .seealso: SNESType, SNESCreate(), SNESDestroy(), SNESGetType(), SNESSetFromOptions() 4854435da068SBarry Smith 48559b94acceSBarry Smith @*/ 485619fd82e9SBarry Smith PetscErrorCode SNESSetType(SNES snes,SNESType type) 48579b94acceSBarry Smith { 4858dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 4859ace3abfcSBarry Smith PetscBool match; 48603a40ed3dSBarry Smith 48613a40ed3dSBarry Smith PetscFunctionBegin; 48620700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 48634482741eSBarry Smith PetscValidCharPointer(type,2); 486482bf6240SBarry Smith 4865251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 48660f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 486792ff6ae8SBarry Smith 48681c9cd337SJed Brown ierr = PetscFunctionListFind(SNESList,type,&r);CHKERRQ(ierr); 4869e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 487075396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 4871b5c23020SJed Brown if (snes->ops->destroy) { 4872b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 48730298fd71SBarry Smith snes->ops->destroy = NULL; 4874b5c23020SJed Brown } 487575396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 48769e5d0892SLisandro Dalcin snes->ops->setup = NULL; 48779e5d0892SLisandro Dalcin snes->ops->solve = NULL; 48789e5d0892SLisandro Dalcin snes->ops->view = NULL; 48799e5d0892SLisandro Dalcin snes->ops->setfromoptions = NULL; 48809e5d0892SLisandro Dalcin snes->ops->destroy = NULL; 48817fe760d5SStefano Zampini 48827fe760d5SStefano Zampini /* It may happen the user has customized the line search before calling SNESSetType */ 48837fe760d5SStefano Zampini if (((PetscObject)snes)->type_name) { 4884d8d34be6SBarry Smith ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 48857fe760d5SStefano Zampini } 48867fe760d5SStefano Zampini 488775396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 488875396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 4889f5af7f23SKarl Rupp 4890454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 489103bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 48923a40ed3dSBarry Smith PetscFunctionReturn(0); 48939b94acceSBarry Smith } 48949b94acceSBarry Smith 48959b94acceSBarry Smith /*@C 48969a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 48979b94acceSBarry Smith 4898c7afd0dbSLois Curfman McInnes Not Collective 4899c7afd0dbSLois Curfman McInnes 49009b94acceSBarry Smith Input Parameter: 49014b0e389bSBarry Smith . snes - nonlinear solver context 49029b94acceSBarry Smith 49039b94acceSBarry Smith Output Parameter: 49043a7fca6bSBarry Smith . type - SNES method (a character string) 49059b94acceSBarry Smith 490636851e7fSLois Curfman McInnes Level: intermediate 490736851e7fSLois Curfman McInnes 49089b94acceSBarry Smith @*/ 490919fd82e9SBarry Smith PetscErrorCode SNESGetType(SNES snes,SNESType *type) 49109b94acceSBarry Smith { 49113a40ed3dSBarry Smith PetscFunctionBegin; 49120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 49134482741eSBarry Smith PetscValidPointer(type,2); 49147adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 49153a40ed3dSBarry Smith PetscFunctionReturn(0); 49169b94acceSBarry Smith } 49179b94acceSBarry Smith 49183cd8a7caSMatthew G. Knepley /*@ 49193cd8a7caSMatthew G. Knepley SNESSetSolution - Sets the solution vector for use by the SNES routines. 49203cd8a7caSMatthew G. Knepley 4921d083f849SBarry Smith Logically Collective on SNES 49223cd8a7caSMatthew G. Knepley 49233cd8a7caSMatthew G. Knepley Input Parameters: 49243cd8a7caSMatthew G. Knepley + snes - the SNES context obtained from SNESCreate() 49253cd8a7caSMatthew G. Knepley - u - the solution vector 49263cd8a7caSMatthew G. Knepley 49273cd8a7caSMatthew G. Knepley Level: beginner 49283cd8a7caSMatthew G. Knepley 49293cd8a7caSMatthew G. Knepley @*/ 49303cd8a7caSMatthew G. Knepley PetscErrorCode SNESSetSolution(SNES snes, Vec u) 49313cd8a7caSMatthew G. Knepley { 49323cd8a7caSMatthew G. Knepley DM dm; 49333cd8a7caSMatthew G. Knepley PetscErrorCode ierr; 49343cd8a7caSMatthew G. Knepley 49353cd8a7caSMatthew G. Knepley PetscFunctionBegin; 49363cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 49373cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 49383cd8a7caSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) u);CHKERRQ(ierr); 49393cd8a7caSMatthew G. Knepley ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 49403cd8a7caSMatthew G. Knepley 49413cd8a7caSMatthew G. Knepley snes->vec_sol = u; 49423cd8a7caSMatthew G. Knepley 49433cd8a7caSMatthew G. Knepley ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 49443cd8a7caSMatthew G. Knepley ierr = DMShellSetGlobalVector(dm, u);CHKERRQ(ierr); 49453cd8a7caSMatthew G. Knepley PetscFunctionReturn(0); 49463cd8a7caSMatthew G. Knepley } 49473cd8a7caSMatthew G. Knepley 494852baeb72SSatish Balay /*@ 49499b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 4950c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 49519b94acceSBarry Smith 4952c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 4953c7afd0dbSLois Curfman McInnes 49549b94acceSBarry Smith Input Parameter: 49559b94acceSBarry Smith . snes - the SNES context 49569b94acceSBarry Smith 49579b94acceSBarry Smith Output Parameter: 49589b94acceSBarry Smith . x - the solution 49599b94acceSBarry Smith 496070e92668SMatthew Knepley Level: intermediate 496136851e7fSLois Curfman McInnes 496285385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 49639b94acceSBarry Smith @*/ 49647087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 49659b94acceSBarry Smith { 49663a40ed3dSBarry Smith PetscFunctionBegin; 49670700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 49684482741eSBarry Smith PetscValidPointer(x,2); 496985385478SLisandro Dalcin *x = snes->vec_sol; 497070e92668SMatthew Knepley PetscFunctionReturn(0); 497170e92668SMatthew Knepley } 497270e92668SMatthew Knepley 497352baeb72SSatish Balay /*@ 49749b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 49759b94acceSBarry Smith stored. 49769b94acceSBarry Smith 4977c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 4978c7afd0dbSLois Curfman McInnes 49799b94acceSBarry Smith Input Parameter: 49809b94acceSBarry Smith . snes - the SNES context 49819b94acceSBarry Smith 49829b94acceSBarry Smith Output Parameter: 49839b94acceSBarry Smith . x - the solution update 49849b94acceSBarry Smith 498536851e7fSLois Curfman McInnes Level: advanced 498636851e7fSLois Curfman McInnes 498785385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 49889b94acceSBarry Smith @*/ 49897087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 49909b94acceSBarry Smith { 49913a40ed3dSBarry Smith PetscFunctionBegin; 49920700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 49934482741eSBarry Smith PetscValidPointer(x,2); 499485385478SLisandro Dalcin *x = snes->vec_sol_update; 49953a40ed3dSBarry Smith PetscFunctionReturn(0); 49969b94acceSBarry Smith } 49979b94acceSBarry Smith 49989b94acceSBarry Smith /*@C 49993638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 50009b94acceSBarry Smith 5001a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 5002c7afd0dbSLois Curfman McInnes 50039b94acceSBarry Smith Input Parameter: 50049b94acceSBarry Smith . snes - the SNES context 50059b94acceSBarry Smith 5006d8d19677SJose E. Roman Output Parameters: 50070298fd71SBarry Smith + r - the vector that is used to store residuals (or NULL if you don't want it) 5008f8b49ee9SBarry Smith . f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details 50090298fd71SBarry Smith - ctx - the function context (or NULL if you don't want it) 50109b94acceSBarry Smith 501136851e7fSLois Curfman McInnes Level: advanced 501236851e7fSLois Curfman McInnes 501304edfde5SBarry Smith Notes: The vector r DOES NOT, in general contain the current value of the SNES nonlinear function 501404edfde5SBarry Smith 5015bf388a1fSBarry Smith .seealso: SNESSetFunction(), SNESGetSolution(), SNESFunction 50169b94acceSBarry Smith @*/ 5017f8b49ee9SBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx) 50189b94acceSBarry Smith { 5019a63bb30eSJed Brown PetscErrorCode ierr; 50206cab3a1bSJed Brown DM dm; 5021a63bb30eSJed Brown 50223a40ed3dSBarry Smith PetscFunctionBegin; 50230700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5024a63bb30eSJed Brown if (r) { 5025a63bb30eSJed Brown if (!snes->vec_func) { 5026a63bb30eSJed Brown if (snes->vec_rhs) { 5027a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 5028a63bb30eSJed Brown } else if (snes->vec_sol) { 5029a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 5030a63bb30eSJed Brown } else if (snes->dm) { 5031a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 5032a63bb30eSJed Brown } 5033a63bb30eSJed Brown } 5034a63bb30eSJed Brown *r = snes->vec_func; 5035a63bb30eSJed Brown } 50366cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 5037f8b49ee9SBarry Smith ierr = DMSNESGetFunction(dm,f,ctx);CHKERRQ(ierr); 50383a40ed3dSBarry Smith PetscFunctionReturn(0); 50399b94acceSBarry Smith } 50409b94acceSBarry Smith 5041c79ef259SPeter Brune /*@C 5042be95d8f1SBarry Smith SNESGetNGS - Returns the NGS function and context. 5043c79ef259SPeter Brune 5044c79ef259SPeter Brune Input Parameter: 5045c79ef259SPeter Brune . snes - the SNES context 5046c79ef259SPeter Brune 5047d8d19677SJose E. Roman Output Parameters: 5048be95d8f1SBarry Smith + f - the function (or NULL) see SNESNGSFunction for details 50490298fd71SBarry Smith - ctx - the function context (or NULL) 5050c79ef259SPeter Brune 5051c79ef259SPeter Brune Level: advanced 5052c79ef259SPeter Brune 5053be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESGetFunction() 5054c79ef259SPeter Brune @*/ 5055c79ef259SPeter Brune 5056be95d8f1SBarry Smith PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx) 5057646217ecSPeter Brune { 50586cab3a1bSJed Brown PetscErrorCode ierr; 50596cab3a1bSJed Brown DM dm; 50606cab3a1bSJed Brown 5061646217ecSPeter Brune PetscFunctionBegin; 5062646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 50636cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 5064be95d8f1SBarry Smith ierr = DMSNESGetNGS(dm,f,ctx);CHKERRQ(ierr); 5065646217ecSPeter Brune PetscFunctionReturn(0); 5066646217ecSPeter Brune } 5067646217ecSPeter Brune 50683c7409f5SSatish Balay /*@C 50693c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 5070d850072dSLois Curfman McInnes SNES options in the database. 50713c7409f5SSatish Balay 50723f9fe445SBarry Smith Logically Collective on SNES 5073fee21e36SBarry Smith 5074d8d19677SJose E. Roman Input Parameters: 5075c7afd0dbSLois Curfman McInnes + snes - the SNES context 5076c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 5077c7afd0dbSLois Curfman McInnes 5078d850072dSLois Curfman McInnes Notes: 5079a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 5080c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 5081d850072dSLois Curfman McInnes 508236851e7fSLois Curfman McInnes Level: advanced 508336851e7fSLois Curfman McInnes 5084a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 50853c7409f5SSatish Balay @*/ 50867087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 50873c7409f5SSatish Balay { 5088dfbe8321SBarry Smith PetscErrorCode ierr; 50893c7409f5SSatish Balay 50903a40ed3dSBarry Smith PetscFunctionBegin; 50910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5092639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 50931cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 509435f5d045SPeter Brune if (snes->linesearch) { 50957601faf0SJed Brown ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 509608b6c495SPeter Brune ierr = PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 509735f5d045SPeter Brune } 509835f5d045SPeter Brune ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 50993a40ed3dSBarry Smith PetscFunctionReturn(0); 51003c7409f5SSatish Balay } 51013c7409f5SSatish Balay 51023c7409f5SSatish Balay /*@C 5103f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 5104d850072dSLois Curfman McInnes SNES options in the database. 51053c7409f5SSatish Balay 51063f9fe445SBarry Smith Logically Collective on SNES 5107fee21e36SBarry Smith 5108c7afd0dbSLois Curfman McInnes Input Parameters: 5109c7afd0dbSLois Curfman McInnes + snes - the SNES context 5110c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 5111c7afd0dbSLois Curfman McInnes 5112d850072dSLois Curfman McInnes Notes: 5113a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 5114c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 5115d850072dSLois Curfman McInnes 511636851e7fSLois Curfman McInnes Level: advanced 511736851e7fSLois Curfman McInnes 5118a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 51193c7409f5SSatish Balay @*/ 51207087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 51213c7409f5SSatish Balay { 5122dfbe8321SBarry Smith PetscErrorCode ierr; 51233c7409f5SSatish Balay 51243a40ed3dSBarry Smith PetscFunctionBegin; 51250700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5126639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 51271cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 512835f5d045SPeter Brune if (snes->linesearch) { 51297601faf0SJed Brown ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 513008b6c495SPeter Brune ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 513135f5d045SPeter Brune } 513235f5d045SPeter Brune ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 51333a40ed3dSBarry Smith PetscFunctionReturn(0); 51343c7409f5SSatish Balay } 51353c7409f5SSatish Balay 51369ab63eb5SSatish Balay /*@C 51373c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 51383c7409f5SSatish Balay SNES options in the database. 51393c7409f5SSatish Balay 5140c7afd0dbSLois Curfman McInnes Not Collective 5141c7afd0dbSLois Curfman McInnes 51423c7409f5SSatish Balay Input Parameter: 51433c7409f5SSatish Balay . snes - the SNES context 51443c7409f5SSatish Balay 51453c7409f5SSatish Balay Output Parameter: 51463c7409f5SSatish Balay . prefix - pointer to the prefix string used 51473c7409f5SSatish Balay 514895452b02SPatrick Sanan Notes: 514995452b02SPatrick Sanan On the fortran side, the user should pass in a string 'prefix' of 51509ab63eb5SSatish Balay sufficient length to hold the prefix. 51519ab63eb5SSatish Balay 515236851e7fSLois Curfman McInnes Level: advanced 515336851e7fSLois Curfman McInnes 5154a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 51553c7409f5SSatish Balay @*/ 51567087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 51573c7409f5SSatish Balay { 5158dfbe8321SBarry Smith PetscErrorCode ierr; 51593c7409f5SSatish Balay 51603a40ed3dSBarry Smith PetscFunctionBegin; 51610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5162639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 51633a40ed3dSBarry Smith PetscFunctionReturn(0); 51643c7409f5SSatish Balay } 51653c7409f5SSatish Balay 51663cea93caSBarry Smith /*@C 51671c84c290SBarry Smith SNESRegister - Adds a method to the nonlinear solver package. 51681c84c290SBarry Smith 51691c84c290SBarry Smith Not collective 51701c84c290SBarry Smith 51711c84c290SBarry Smith Input Parameters: 51721c84c290SBarry Smith + name_solver - name of a new user-defined solver 51731c84c290SBarry Smith - routine_create - routine to create method context 51741c84c290SBarry Smith 51751c84c290SBarry Smith Notes: 51761c84c290SBarry Smith SNESRegister() may be called multiple times to add several user-defined solvers. 51771c84c290SBarry Smith 51781c84c290SBarry Smith Sample usage: 51791c84c290SBarry Smith .vb 5180bdf89e91SBarry Smith SNESRegister("my_solver",MySolverCreate); 51811c84c290SBarry Smith .ve 51821c84c290SBarry Smith 51831c84c290SBarry Smith Then, your solver can be chosen with the procedural interface via 51841c84c290SBarry Smith $ SNESSetType(snes,"my_solver") 51851c84c290SBarry Smith or at runtime via the option 51861c84c290SBarry Smith $ -snes_type my_solver 51871c84c290SBarry Smith 51881c84c290SBarry Smith Level: advanced 51891c84c290SBarry Smith 51901c84c290SBarry Smith Note: If your function is not being put into a shared library then use SNESRegister() instead 51911c84c290SBarry Smith 51921c84c290SBarry Smith .seealso: SNESRegisterAll(), SNESRegisterDestroy() 51933cea93caSBarry Smith 51947f6c08e0SMatthew Knepley Level: advanced 51953cea93caSBarry Smith @*/ 5196bdf89e91SBarry Smith PetscErrorCode SNESRegister(const char sname[],PetscErrorCode (*function)(SNES)) 5197b2002411SLois Curfman McInnes { 5198dfbe8321SBarry Smith PetscErrorCode ierr; 5199b2002411SLois Curfman McInnes 5200b2002411SLois Curfman McInnes PetscFunctionBegin; 52011d36bdfdSBarry Smith ierr = SNESInitializePackage();CHKERRQ(ierr); 5202a240a19fSJed Brown ierr = PetscFunctionListAdd(&SNESList,sname,function);CHKERRQ(ierr); 5203b2002411SLois Curfman McInnes PetscFunctionReturn(0); 5204b2002411SLois Curfman McInnes } 5205da9b6338SBarry Smith 52067087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 5207da9b6338SBarry Smith { 5208dfbe8321SBarry Smith PetscErrorCode ierr; 520977431f27SBarry Smith PetscInt N,i,j; 5210da9b6338SBarry Smith Vec u,uh,fh; 5211da9b6338SBarry Smith PetscScalar value; 5212da9b6338SBarry Smith PetscReal norm; 5213da9b6338SBarry Smith 5214da9b6338SBarry Smith PetscFunctionBegin; 5215da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 5216da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 5217da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 5218da9b6338SBarry Smith 5219da9b6338SBarry Smith /* currently only works for sequential */ 5220ea13f565SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"Testing FormFunction() for local min\n");CHKERRQ(ierr); 5221da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 5222da9b6338SBarry Smith for (i=0; i<N; i++) { 5223da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 5224ea13f565SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"i = %D\n",i);CHKERRQ(ierr); 5225da9b6338SBarry Smith for (j=-10; j<11; j++) { 52268b49ba18SBarry Smith value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0); 5227da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 52283ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 5229da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 5230ea13f565SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)snes)," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 5231da9b6338SBarry Smith value = -value; 5232da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 5233da9b6338SBarry Smith } 5234da9b6338SBarry Smith } 52356bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 52366bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 5237da9b6338SBarry Smith PetscFunctionReturn(0); 5238da9b6338SBarry Smith } 523971f87433Sdalcinl 524071f87433Sdalcinl /*@ 5241fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 524271f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 524371f87433Sdalcinl Newton method. 524471f87433Sdalcinl 52453f9fe445SBarry Smith Logically Collective on SNES 524671f87433Sdalcinl 524771f87433Sdalcinl Input Parameters: 524871f87433Sdalcinl + snes - SNES context 524971f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 525071f87433Sdalcinl 525164ba62caSBarry Smith Options Database: 525264ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 525364ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 525464ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 525564ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 525664ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 525764ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 525864ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 525964ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 526064ba62caSBarry Smith 526171f87433Sdalcinl Notes: 526271f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 526371f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 526471f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 526571f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 526671f87433Sdalcinl solver. 526771f87433Sdalcinl 526871f87433Sdalcinl Level: advanced 526971f87433Sdalcinl 527071f87433Sdalcinl Reference: 527171f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 527271f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 527371f87433Sdalcinl 5274fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 527571f87433Sdalcinl @*/ 52767087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 527771f87433Sdalcinl { 527871f87433Sdalcinl PetscFunctionBegin; 52790700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5280acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 528171f87433Sdalcinl snes->ksp_ewconv = flag; 528271f87433Sdalcinl PetscFunctionReturn(0); 528371f87433Sdalcinl } 528471f87433Sdalcinl 528571f87433Sdalcinl /*@ 5286fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 528771f87433Sdalcinl for computing relative tolerance for linear solvers within an 528871f87433Sdalcinl inexact Newton method. 528971f87433Sdalcinl 529071f87433Sdalcinl Not Collective 529171f87433Sdalcinl 529271f87433Sdalcinl Input Parameter: 529371f87433Sdalcinl . snes - SNES context 529471f87433Sdalcinl 529571f87433Sdalcinl Output Parameter: 529671f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 529771f87433Sdalcinl 529871f87433Sdalcinl Notes: 529971f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 530071f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 530171f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 530271f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 530371f87433Sdalcinl solver. 530471f87433Sdalcinl 530571f87433Sdalcinl Level: advanced 530671f87433Sdalcinl 530771f87433Sdalcinl Reference: 530871f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 530971f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 531071f87433Sdalcinl 5311fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 531271f87433Sdalcinl @*/ 53137087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 531471f87433Sdalcinl { 531571f87433Sdalcinl PetscFunctionBegin; 53160700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5317534a8f05SLisandro Dalcin PetscValidBoolPointer(flag,2); 531871f87433Sdalcinl *flag = snes->ksp_ewconv; 531971f87433Sdalcinl PetscFunctionReturn(0); 532071f87433Sdalcinl } 532171f87433Sdalcinl 532271f87433Sdalcinl /*@ 5323fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 532471f87433Sdalcinl convergence criteria for the linear solvers within an inexact 532571f87433Sdalcinl Newton method. 532671f87433Sdalcinl 53273f9fe445SBarry Smith Logically Collective on SNES 532871f87433Sdalcinl 532971f87433Sdalcinl Input Parameters: 533071f87433Sdalcinl + snes - SNES context 533171f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 533271f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 533371f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 533471f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 533571f87433Sdalcinl (0 <= gamma2 <= 1) 533671f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 533771f87433Sdalcinl . alpha2 - power for safeguard 533871f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 533971f87433Sdalcinl 534071f87433Sdalcinl Note: 534171f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 534271f87433Sdalcinl 534371f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 534471f87433Sdalcinl 534571f87433Sdalcinl Level: advanced 534671f87433Sdalcinl 534771f87433Sdalcinl Reference: 534871f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 534971f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 535071f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 535171f87433Sdalcinl 5352fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 535371f87433Sdalcinl @*/ 5354f5af7f23SKarl Rupp PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 535571f87433Sdalcinl { 5356fa9f3622SBarry Smith SNESKSPEW *kctx; 53575fd66863SKarl Rupp 535871f87433Sdalcinl PetscFunctionBegin; 53590700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5360fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 5361e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 5362c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 5363c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 5364c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 5365c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 5366c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 5367c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 5368c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 536971f87433Sdalcinl 537071f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 537171f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 537271f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 537371f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 537471f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 537571f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 537671f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 537771f87433Sdalcinl 5378f23aa3ddSBarry Smith if (kctx->version < 1 || kctx->version > 3) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 537957622a8eSBarry Smith if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %g",(double)kctx->rtol_0); 538057622a8eSBarry Smith if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%g) < 1.0\n",(double)kctx->rtol_max); 538157622a8eSBarry Smith if (kctx->gamma < 0.0 || kctx->gamma > 1.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%g) <= 1.0\n",(double)kctx->gamma); 538257622a8eSBarry Smith if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%g) <= 2.0\n",(double)kctx->alpha); 538357622a8eSBarry Smith if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%g) < 1.0\n",(double)kctx->threshold); 538471f87433Sdalcinl PetscFunctionReturn(0); 538571f87433Sdalcinl } 538671f87433Sdalcinl 538771f87433Sdalcinl /*@ 5388fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 538971f87433Sdalcinl convergence criteria for the linear solvers within an inexact 539071f87433Sdalcinl Newton method. 539171f87433Sdalcinl 539271f87433Sdalcinl Not Collective 539371f87433Sdalcinl 539497bb3fdcSJose E. Roman Input Parameter: 53956b867d5aSJose E. Roman . snes - SNES context 539671f87433Sdalcinl 539771f87433Sdalcinl Output Parameters: 539871f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 539971f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 540071f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 5401bf388a1fSBarry Smith . gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1) 540271f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 540371f87433Sdalcinl . alpha2 - power for safeguard 540471f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 540571f87433Sdalcinl 540671f87433Sdalcinl Level: advanced 540771f87433Sdalcinl 5408fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 540971f87433Sdalcinl @*/ 5410bf388a1fSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 541171f87433Sdalcinl { 5412fa9f3622SBarry Smith SNESKSPEW *kctx; 54135fd66863SKarl Rupp 541471f87433Sdalcinl PetscFunctionBegin; 54150700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5416fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 5417e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 541871f87433Sdalcinl if (version) *version = kctx->version; 541971f87433Sdalcinl if (rtol_0) *rtol_0 = kctx->rtol_0; 542071f87433Sdalcinl if (rtol_max) *rtol_max = kctx->rtol_max; 542171f87433Sdalcinl if (gamma) *gamma = kctx->gamma; 542271f87433Sdalcinl if (alpha) *alpha = kctx->alpha; 542371f87433Sdalcinl if (alpha2) *alpha2 = kctx->alpha2; 542471f87433Sdalcinl if (threshold) *threshold = kctx->threshold; 542571f87433Sdalcinl PetscFunctionReturn(0); 542671f87433Sdalcinl } 542771f87433Sdalcinl 5428d5378b5fSDmitry Karpeev PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 542971f87433Sdalcinl { 543071f87433Sdalcinl PetscErrorCode ierr; 5431fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 543271f87433Sdalcinl PetscReal rtol = PETSC_DEFAULT,stol; 543371f87433Sdalcinl 543471f87433Sdalcinl PetscFunctionBegin; 5435d4211eb9SBarry Smith if (!snes->ksp_ewconv) PetscFunctionReturn(0); 543630058271SDmitry Karpeev if (!snes->iter) { 543730058271SDmitry Karpeev rtol = kctx->rtol_0; /* first time in, so use the original user rtol */ 543830058271SDmitry Karpeev ierr = VecNorm(snes->vec_func,NORM_2,&kctx->norm_first);CHKERRQ(ierr); 543930058271SDmitry Karpeev } 5440f5af7f23SKarl Rupp else { 544171f87433Sdalcinl if (kctx->version == 1) { 544271f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 544371f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 544485ec1a3cSBarry Smith stol = PetscPowReal(kctx->rtol_last,kctx->alpha2); 544571f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 544671f87433Sdalcinl } else if (kctx->version == 2) { 544785ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 544885ec1a3cSBarry Smith stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha); 544971f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 545071f87433Sdalcinl } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */ 545185ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 545271f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 545385ec1a3cSBarry Smith stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha); 545471f87433Sdalcinl stol = PetscMax(rtol,stol); 545571f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 545671f87433Sdalcinl /* safeguard: avoid oversolving */ 545730058271SDmitry Karpeev stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm; 545871f87433Sdalcinl stol = PetscMax(rtol,stol); 545971f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 5460e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 546171f87433Sdalcinl } 546271f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 546371f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 546471f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 546557622a8eSBarry Smith ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol);CHKERRQ(ierr); 546671f87433Sdalcinl PetscFunctionReturn(0); 546771f87433Sdalcinl } 546871f87433Sdalcinl 5469d5378b5fSDmitry Karpeev PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 547071f87433Sdalcinl { 547171f87433Sdalcinl PetscErrorCode ierr; 5472fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 547371f87433Sdalcinl PCSide pcside; 547471f87433Sdalcinl Vec lres; 547571f87433Sdalcinl 547671f87433Sdalcinl PetscFunctionBegin; 5477d4211eb9SBarry Smith if (!snes->ksp_ewconv) PetscFunctionReturn(0); 54789e5d0892SLisandro Dalcin ierr = KSPGetTolerances(ksp,&kctx->rtol_last,NULL,NULL,NULL);CHKERRQ(ierr); 547971dbe336SPeter Brune kctx->norm_last = snes->norm; 548071f87433Sdalcinl if (kctx->version == 1) { 54814f00ce20SMatthew G. Knepley PC pc; 54824f00ce20SMatthew G. Knepley PetscBool isNone; 54834f00ce20SMatthew G. Knepley 54844f00ce20SMatthew G. Knepley ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr); 54854f00ce20SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) pc, PCNONE, &isNone);CHKERRQ(ierr); 5486b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 54874f00ce20SMatthew G. Knepley if (pcside == PC_RIGHT || isNone) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 548871f87433Sdalcinl /* KSP residual is true linear residual */ 548971f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 549071f87433Sdalcinl } else { 549171f87433Sdalcinl /* KSP residual is preconditioned residual */ 549271f87433Sdalcinl /* compute true linear residual norm */ 549371f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 549471f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 549571f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 549671f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 54976bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 549871f87433Sdalcinl } 549971f87433Sdalcinl } 550071f87433Sdalcinl PetscFunctionReturn(0); 550171f87433Sdalcinl } 550271f87433Sdalcinl 5503d4211eb9SBarry Smith /*@ 5504d4211eb9SBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 5505d4211eb9SBarry Smith 5506d4211eb9SBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 5507d4211eb9SBarry Smith 5508d4211eb9SBarry Smith Input Parameter: 5509d4211eb9SBarry Smith . snes - the SNES context 5510d4211eb9SBarry Smith 5511d4211eb9SBarry Smith Output Parameter: 5512d4211eb9SBarry Smith . ksp - the KSP context 5513d4211eb9SBarry Smith 5514d4211eb9SBarry Smith Notes: 5515d4211eb9SBarry Smith The user can then directly manipulate the KSP context to set various 5516d4211eb9SBarry Smith options, etc. Likewise, the user can then extract and manipulate the 5517d4211eb9SBarry Smith PC contexts as well. 5518d4211eb9SBarry Smith 5519d4211eb9SBarry Smith Level: beginner 5520d4211eb9SBarry Smith 5521d4211eb9SBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 5522d4211eb9SBarry Smith @*/ 5523d4211eb9SBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 552471f87433Sdalcinl { 552571f87433Sdalcinl PetscErrorCode ierr; 552671f87433Sdalcinl 552771f87433Sdalcinl PetscFunctionBegin; 5528d4211eb9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5529d4211eb9SBarry Smith PetscValidPointer(ksp,2); 5530d4211eb9SBarry Smith 5531d4211eb9SBarry Smith if (!snes->ksp) { 5532d4211eb9SBarry Smith ierr = KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp);CHKERRQ(ierr); 5533d4211eb9SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 55343bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp);CHKERRQ(ierr); 5535d4211eb9SBarry Smith 5536d5378b5fSDmitry Karpeev ierr = KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes);CHKERRQ(ierr); 5537d5378b5fSDmitry Karpeev ierr = KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes);CHKERRQ(ierr); 5538a5c2985bSBarry Smith 5539798534f6SMatthew G. Knepley ierr = KSPMonitorSetFromOptions(snes->ksp, "-snes_monitor_ksp", "snes_preconditioned_residual", snes);CHKERRQ(ierr); 554016413a6aSBarry Smith ierr = PetscObjectSetOptions((PetscObject)snes->ksp,((PetscObject)snes)->options);CHKERRQ(ierr); 5541d4211eb9SBarry Smith } 5542d4211eb9SBarry Smith *ksp = snes->ksp; 554371f87433Sdalcinl PetscFunctionReturn(0); 554471f87433Sdalcinl } 55456c699258SBarry Smith 5546af0996ceSBarry Smith #include <petsc/private/dmimpl.h> 55476c699258SBarry Smith /*@ 55482a808120SBarry Smith SNESSetDM - Sets the DM that may be used by some nonlinear solvers or their underlying preconditioners 55496c699258SBarry Smith 55503f9fe445SBarry Smith Logically Collective on SNES 55516c699258SBarry Smith 55526c699258SBarry Smith Input Parameters: 55532a808120SBarry Smith + snes - the nonlinear solver context 55542a808120SBarry Smith - dm - the dm, cannot be NULL 55556c699258SBarry Smith 5556e03a659cSJed Brown Notes: 5557e03a659cSJed Brown A DM can only be used for solving one problem at a time because information about the problem is stored on the DM, 5558e03a659cSJed Brown even when not using interfaces like DMSNESSetFunction(). Use DMClone() to get a distinct DM when solving different 5559e03a659cSJed Brown problems using the same function space. 5560e03a659cSJed Brown 55616c699258SBarry Smith Level: intermediate 55626c699258SBarry Smith 55634c2026ceSFande Kong .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 55646c699258SBarry Smith @*/ 55657087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 55666c699258SBarry Smith { 55676c699258SBarry Smith PetscErrorCode ierr; 5568345fed2cSBarry Smith KSP ksp; 5569942e3340SBarry Smith DMSNES sdm; 55706c699258SBarry Smith 55716c699258SBarry Smith PetscFunctionBegin; 55720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 55732a808120SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,2); 55742a808120SBarry Smith ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 5575942e3340SBarry Smith if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */ 557651f4b3c7SToby Isaac if (snes->dm->dmsnes && !dm->dmsnes) { 5577942e3340SBarry Smith ierr = DMCopyDMSNES(snes->dm,dm);CHKERRQ(ierr); 5578942e3340SBarry Smith ierr = DMGetDMSNES(snes->dm,&sdm);CHKERRQ(ierr); 5579f5af7f23SKarl Rupp if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */ 55806cab3a1bSJed Brown } 5581dc822a44SJed Brown ierr = DMCoarsenHookRemove(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 55826bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 55836cab3a1bSJed Brown } 55846c699258SBarry Smith snes->dm = dm; 5585116d1032SJed Brown snes->dmAuto = PETSC_FALSE; 5586f5af7f23SKarl Rupp 5587345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 5588345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 5589f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 5590efd4aadfSBarry Smith if (snes->npc) { 5591efd4aadfSBarry Smith ierr = SNESSetDM(snes->npc, snes->dm);CHKERRQ(ierr); 5592efd4aadfSBarry Smith ierr = SNESSetNPCSide(snes,snes->npcside);CHKERRQ(ierr); 55932c155ee1SBarry Smith } 55946c699258SBarry Smith PetscFunctionReturn(0); 55956c699258SBarry Smith } 55966c699258SBarry Smith 55976c699258SBarry Smith /*@ 55986c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 55996c699258SBarry Smith 56003f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 56016c699258SBarry Smith 56026c699258SBarry Smith Input Parameter: 56036c699258SBarry Smith . snes - the preconditioner context 56046c699258SBarry Smith 56056c699258SBarry Smith Output Parameter: 56066c699258SBarry Smith . dm - the dm 56076c699258SBarry Smith 56086c699258SBarry Smith Level: intermediate 56096c699258SBarry Smith 56104c2026ceSFande Kong .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 56116c699258SBarry Smith @*/ 56127087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 56136c699258SBarry Smith { 56146cab3a1bSJed Brown PetscErrorCode ierr; 56156cab3a1bSJed Brown 56166c699258SBarry Smith PetscFunctionBegin; 56170700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 56186cab3a1bSJed Brown if (!snes->dm) { 5619ce94432eSBarry Smith ierr = DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm);CHKERRQ(ierr); 5620116d1032SJed Brown snes->dmAuto = PETSC_TRUE; 56216cab3a1bSJed Brown } 56226c699258SBarry Smith *dm = snes->dm; 56236c699258SBarry Smith PetscFunctionReturn(0); 56246c699258SBarry Smith } 56250807856dSBarry Smith 562631823bd8SMatthew G Knepley /*@ 5627be95d8f1SBarry Smith SNESSetNPC - Sets the nonlinear preconditioner to be used. 562831823bd8SMatthew G Knepley 562931823bd8SMatthew G Knepley Collective on SNES 563031823bd8SMatthew G Knepley 563131823bd8SMatthew G Knepley Input Parameters: 563231823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 563331823bd8SMatthew G Knepley - pc - the preconditioner object 563431823bd8SMatthew G Knepley 563531823bd8SMatthew G Knepley Notes: 5636be95d8f1SBarry Smith Use SNESGetNPC() to retrieve the preconditioner context (for example, 563731823bd8SMatthew G Knepley to configure it using the API). 563831823bd8SMatthew G Knepley 563931823bd8SMatthew G Knepley Level: developer 564031823bd8SMatthew G Knepley 56413ad1a0b9SPatrick Farrell .seealso: SNESGetNPC(), SNESHasNPC() 564231823bd8SMatthew G Knepley @*/ 5643be95d8f1SBarry Smith PetscErrorCode SNESSetNPC(SNES snes, SNES pc) 564431823bd8SMatthew G Knepley { 564531823bd8SMatthew G Knepley PetscErrorCode ierr; 564631823bd8SMatthew G Knepley 564731823bd8SMatthew G Knepley PetscFunctionBegin; 564831823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 564931823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 565031823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 565131823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 5652efd4aadfSBarry Smith ierr = SNESDestroy(&snes->npc);CHKERRQ(ierr); 5653efd4aadfSBarry Smith snes->npc = pc; 5654efd4aadfSBarry Smith ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->npc);CHKERRQ(ierr); 565531823bd8SMatthew G Knepley PetscFunctionReturn(0); 565631823bd8SMatthew G Knepley } 565731823bd8SMatthew G Knepley 565831823bd8SMatthew G Knepley /*@ 5659be95d8f1SBarry Smith SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver. 566031823bd8SMatthew G Knepley 5661951fe5abSBarry Smith Not Collective; but any changes to the obtained SNES object must be applied collectively 566231823bd8SMatthew G Knepley 566331823bd8SMatthew G Knepley Input Parameter: 566431823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 566531823bd8SMatthew G Knepley 566631823bd8SMatthew G Knepley Output Parameter: 566731823bd8SMatthew G Knepley . pc - preconditioner context 566831823bd8SMatthew G Knepley 5669b5badacbSBarry Smith Options Database: 5670b5badacbSBarry Smith . -npc_snes_type <type> - set the type of the SNES to use as the nonlinear preconditioner 5671b5badacbSBarry Smith 567295452b02SPatrick Sanan Notes: 5673b5badacbSBarry Smith If a SNES was previously set with SNESSetNPC() then that SNES is returned, otherwise a new SNES object is created. 5674be95d8f1SBarry Smith 5675951fe5abSBarry Smith The (preconditioner) SNES returned automatically inherits the same nonlinear function and Jacobian supplied to the original 5676951fe5abSBarry Smith SNES during SNESSetUp() 5677951fe5abSBarry Smith 567831823bd8SMatthew G Knepley Level: developer 567931823bd8SMatthew G Knepley 5680951fe5abSBarry Smith .seealso: SNESSetNPC(), SNESHasNPC(), SNES, SNESCreate() 568131823bd8SMatthew G Knepley @*/ 5682be95d8f1SBarry Smith PetscErrorCode SNESGetNPC(SNES snes, SNES *pc) 568331823bd8SMatthew G Knepley { 568431823bd8SMatthew G Knepley PetscErrorCode ierr; 5685a64e098fSPeter Brune const char *optionsprefix; 568631823bd8SMatthew G Knepley 568731823bd8SMatthew G Knepley PetscFunctionBegin; 568831823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 568931823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 5690efd4aadfSBarry Smith if (!snes->npc) { 5691efd4aadfSBarry Smith ierr = SNESCreate(PetscObjectComm((PetscObject)snes),&snes->npc);CHKERRQ(ierr); 5692efd4aadfSBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->npc,(PetscObject)snes,1);CHKERRQ(ierr); 5693efd4aadfSBarry Smith ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr); 5694a64e098fSPeter Brune ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr); 5695efd4aadfSBarry Smith ierr = SNESSetOptionsPrefix(snes->npc,optionsprefix);CHKERRQ(ierr); 5696efd4aadfSBarry Smith ierr = SNESAppendOptionsPrefix(snes->npc,"npc_");CHKERRQ(ierr); 5697efd4aadfSBarry Smith ierr = SNESSetCountersReset(snes->npc,PETSC_FALSE);CHKERRQ(ierr); 569831823bd8SMatthew G Knepley } 5699efd4aadfSBarry Smith *pc = snes->npc; 570031823bd8SMatthew G Knepley PetscFunctionReturn(0); 570131823bd8SMatthew G Knepley } 570231823bd8SMatthew G Knepley 57033ad1a0b9SPatrick Farrell /*@ 57043ad1a0b9SPatrick Farrell SNESHasNPC - Returns whether a nonlinear preconditioner exists 57053ad1a0b9SPatrick Farrell 57063ad1a0b9SPatrick Farrell Not Collective 57073ad1a0b9SPatrick Farrell 57083ad1a0b9SPatrick Farrell Input Parameter: 57093ad1a0b9SPatrick Farrell . snes - iterative context obtained from SNESCreate() 57103ad1a0b9SPatrick Farrell 57113ad1a0b9SPatrick Farrell Output Parameter: 57123ad1a0b9SPatrick Farrell . has_npc - whether the SNES has an NPC or not 57133ad1a0b9SPatrick Farrell 57143ad1a0b9SPatrick Farrell Level: developer 57153ad1a0b9SPatrick Farrell 57163ad1a0b9SPatrick Farrell .seealso: SNESSetNPC(), SNESGetNPC() 57173ad1a0b9SPatrick Farrell @*/ 57183ad1a0b9SPatrick Farrell PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc) 57193ad1a0b9SPatrick Farrell { 57203ad1a0b9SPatrick Farrell PetscFunctionBegin; 57213ad1a0b9SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5722efd4aadfSBarry Smith *has_npc = (PetscBool) (snes->npc ? PETSC_TRUE : PETSC_FALSE); 57233ad1a0b9SPatrick Farrell PetscFunctionReturn(0); 57243ad1a0b9SPatrick Farrell } 57253ad1a0b9SPatrick Farrell 5726c40d0f55SPeter Brune /*@ 5727be95d8f1SBarry Smith SNESSetNPCSide - Sets the preconditioning side. 5728c40d0f55SPeter Brune 5729c40d0f55SPeter Brune Logically Collective on SNES 5730c40d0f55SPeter Brune 5731c40d0f55SPeter Brune Input Parameter: 5732c40d0f55SPeter Brune . snes - iterative context obtained from SNESCreate() 5733c40d0f55SPeter Brune 5734c40d0f55SPeter Brune Output Parameter: 5735c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5736c40d0f55SPeter Brune .vb 57372d547940SBarry Smith PC_LEFT - left preconditioning 57382d547940SBarry Smith PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5739c40d0f55SPeter Brune .ve 5740c40d0f55SPeter Brune 5741c40d0f55SPeter Brune Options Database Keys: 57421af0b375SJunchao Zhang . -snes_npc_side <right,left> 5743c40d0f55SPeter Brune 574495452b02SPatrick Sanan Notes: 574595452b02SPatrick Sanan SNESNRICHARDSON and SNESNCG only support left preconditioning. 57462d547940SBarry Smith 5747c40d0f55SPeter Brune Level: intermediate 5748c40d0f55SPeter Brune 5749be95d8f1SBarry Smith .seealso: SNESGetNPCSide(), KSPSetPCSide() 5750c40d0f55SPeter Brune @*/ 5751be95d8f1SBarry Smith PetscErrorCode SNESSetNPCSide(SNES snes,PCSide side) 5752c40d0f55SPeter Brune { 5753c40d0f55SPeter Brune PetscFunctionBegin; 5754c40d0f55SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5755c40d0f55SPeter Brune PetscValidLogicalCollectiveEnum(snes,side,2); 5756efd4aadfSBarry Smith snes->npcside= side; 5757c40d0f55SPeter Brune PetscFunctionReturn(0); 5758c40d0f55SPeter Brune } 5759c40d0f55SPeter Brune 5760c40d0f55SPeter Brune /*@ 5761be95d8f1SBarry Smith SNESGetNPCSide - Gets the preconditioning side. 5762c40d0f55SPeter Brune 5763c40d0f55SPeter Brune Not Collective 5764c40d0f55SPeter Brune 5765c40d0f55SPeter Brune Input Parameter: 5766c40d0f55SPeter Brune . snes - iterative context obtained from SNESCreate() 5767c40d0f55SPeter Brune 5768c40d0f55SPeter Brune Output Parameter: 5769c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5770c40d0f55SPeter Brune .vb 57712d547940SBarry Smith PC_LEFT - left preconditioning 57722d547940SBarry Smith PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5773c40d0f55SPeter Brune .ve 5774c40d0f55SPeter Brune 5775c40d0f55SPeter Brune Level: intermediate 5776c40d0f55SPeter Brune 5777be95d8f1SBarry Smith .seealso: SNESSetNPCSide(), KSPGetPCSide() 5778c40d0f55SPeter Brune @*/ 5779be95d8f1SBarry Smith PetscErrorCode SNESGetNPCSide(SNES snes,PCSide *side) 5780c40d0f55SPeter Brune { 5781c40d0f55SPeter Brune PetscFunctionBegin; 5782c40d0f55SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5783c40d0f55SPeter Brune PetscValidPointer(side,2); 5784efd4aadfSBarry Smith *side = snes->npcside; 5785c40d0f55SPeter Brune PetscFunctionReturn(0); 5786c40d0f55SPeter Brune } 5787c40d0f55SPeter Brune 57889e764e56SPeter Brune /*@ 57897601faf0SJed Brown SNESSetLineSearch - Sets the linesearch on the SNES instance. 57909e764e56SPeter Brune 57919e764e56SPeter Brune Collective on SNES 57929e764e56SPeter Brune 57939e764e56SPeter Brune Input Parameters: 57949e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 57959e764e56SPeter Brune - linesearch - the linesearch object 57969e764e56SPeter Brune 57979e764e56SPeter Brune Notes: 57987601faf0SJed Brown Use SNESGetLineSearch() to retrieve the preconditioner context (for example, 57999e764e56SPeter Brune to configure it using the API). 58009e764e56SPeter Brune 58019e764e56SPeter Brune Level: developer 58029e764e56SPeter Brune 58037601faf0SJed Brown .seealso: SNESGetLineSearch() 58049e764e56SPeter Brune @*/ 58057601faf0SJed Brown PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch) 58069e764e56SPeter Brune { 58079e764e56SPeter Brune PetscErrorCode ierr; 58089e764e56SPeter Brune 58099e764e56SPeter Brune PetscFunctionBegin; 58109e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5811f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 58129e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 58139e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 5814f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 5815f5af7f23SKarl Rupp 58169e764e56SPeter Brune snes->linesearch = linesearch; 5817f5af7f23SKarl Rupp 58183bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr); 58199e764e56SPeter Brune PetscFunctionReturn(0); 58209e764e56SPeter Brune } 58219e764e56SPeter Brune 5822a34ceb2aSJed Brown /*@ 58237601faf0SJed Brown SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 58248141a3b9SPeter Brune or creates a default line search instance associated with the SNES and returns it. 58259e764e56SPeter Brune 58269e764e56SPeter Brune Not Collective 58279e764e56SPeter Brune 58289e764e56SPeter Brune Input Parameter: 58299e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 58309e764e56SPeter Brune 58319e764e56SPeter Brune Output Parameter: 58329e764e56SPeter Brune . linesearch - linesearch context 58339e764e56SPeter Brune 5834162e0bf5SPeter Brune Level: beginner 58359e764e56SPeter Brune 5836162e0bf5SPeter Brune .seealso: SNESSetLineSearch(), SNESLineSearchCreate() 58379e764e56SPeter Brune @*/ 58387601faf0SJed Brown PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch) 58399e764e56SPeter Brune { 58409e764e56SPeter Brune PetscErrorCode ierr; 58419e764e56SPeter Brune const char *optionsprefix; 58429e764e56SPeter Brune 58439e764e56SPeter Brune PetscFunctionBegin; 58449e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 58459e764e56SPeter Brune PetscValidPointer(linesearch, 2); 58469e764e56SPeter Brune if (!snes->linesearch) { 58479e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 584882f516ccSBarry Smith ierr = SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch);CHKERRQ(ierr); 5849f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 5850b1dca40bSPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 58519e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 58523bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr); 58539e764e56SPeter Brune } 58549e764e56SPeter Brune *linesearch = snes->linesearch; 58559e764e56SPeter Brune PetscFunctionReturn(0); 58569e764e56SPeter Brune } 5857