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 33e113a28aSBarry Smith .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 57e113a28aSBarry Smith .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) { 461789d8953SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is applied matrix-free with differencing, no explict 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); 47655849f57SBarry Smith if (!rank) { 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); 506d45a07a7SBarry Smith if (!((PetscObject)snes)->amsmem && !rank) { 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 7366cab3a1bSJed Brown Input Arguments: 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: 896ec5066bdSBarry Smith SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free, and computing explictly 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 994fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor","Monitor norm of function","SNESMonitorDefault",SNESMonitorDefault,NULL);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: 1255ec5066bdSBarry Smith SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free, and computing explictly 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 1346360c497dSPeter Brune Input Parameter: 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 1598971e163fSPeter Brune Input Parameter: 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 161882bf6240SBarry Smith 16192999313aSBarry Smith /*@ 16202999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 16212999313aSBarry Smith 16222999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 16232999313aSBarry Smith 16242999313aSBarry Smith Input Parameters: 16252999313aSBarry Smith + snes - the SNES context 16262999313aSBarry Smith - ksp - the KSP context 16272999313aSBarry Smith 16282999313aSBarry Smith Notes: 16292999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 16302999313aSBarry Smith so this routine is rarely needed. 16312999313aSBarry Smith 16322999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 16332999313aSBarry Smith decreased by one. 16342999313aSBarry Smith 16352999313aSBarry Smith Level: developer 16362999313aSBarry Smith 16372999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 16382999313aSBarry Smith @*/ 16397087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 16402999313aSBarry Smith { 16412999313aSBarry Smith PetscErrorCode ierr; 16422999313aSBarry Smith 16432999313aSBarry Smith PetscFunctionBegin; 16440700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16450700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 16462999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 16477dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1648906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 16492999313aSBarry Smith snes->ksp = ksp; 16502999313aSBarry Smith PetscFunctionReturn(0); 16512999313aSBarry Smith } 16522999313aSBarry Smith 16539b94acceSBarry Smith /* -----------------------------------------------------------*/ 165452baeb72SSatish Balay /*@ 16559b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 16569b94acceSBarry Smith 1657d083f849SBarry Smith Collective 1658c7afd0dbSLois Curfman McInnes 1659c7afd0dbSLois Curfman McInnes Input Parameters: 1660906ed7ccSBarry Smith . comm - MPI communicator 16619b94acceSBarry Smith 16629b94acceSBarry Smith Output Parameter: 16639b94acceSBarry Smith . outsnes - the new SNES context 16649b94acceSBarry Smith 1665c7afd0dbSLois Curfman McInnes Options Database Keys: 1666c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1667c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1668c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1669c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1670c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1671c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1672c1f60f51SBarry Smith 167336851e7fSLois Curfman McInnes Level: beginner 167436851e7fSLois Curfman McInnes 167595452b02SPatrick Sanan Developer Notes: 167695452b02SPatrick Sanan SNES always creates a KSP object even though many SNES methods do not use it. This is 1677efd4aadfSBarry Smith unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the 1678efd4aadfSBarry Smith particular method does use KSP and regulates if the information about the KSP is printed 1679efd4aadfSBarry Smith in SNESView(). TSSetFromOptions() does call SNESSetFromOptions() which can lead to users being confused 1680efd4aadfSBarry Smith by help messages about meaningless SNES options. 1681efd4aadfSBarry Smith 1682efd4aadfSBarry Smith SNES always creates the snes->kspconvctx even though it is used by only one type. This should 1683efd4aadfSBarry Smith be fixed. 1684efd4aadfSBarry Smith 16853d5a8a6aSBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner(), SNESSetLagJacobian() 1686a8054027SBarry Smith 16879b94acceSBarry Smith @*/ 16887087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 16899b94acceSBarry Smith { 1690dfbe8321SBarry Smith PetscErrorCode ierr; 16919b94acceSBarry Smith SNES snes; 1692fa9f3622SBarry Smith SNESKSPEW *kctx; 169337fcc0dbSBarry Smith 16943a40ed3dSBarry Smith PetscFunctionBegin; 1695ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 16960298fd71SBarry Smith *outsnes = NULL; 1697607a6623SBarry Smith ierr = SNESInitializePackage();CHKERRQ(ierr); 16988ba1e511SMatthew Knepley 169973107ff1SLisandro Dalcin ierr = PetscHeaderCreate(snes,SNES_CLASSID,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 17007adad957SLisandro Dalcin 17018d359177SBarry Smith snes->ops->converged = SNESConvergedDefault; 17022c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 170388976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 17049b94acceSBarry Smith snes->max_its = 50; 17059750a799SBarry Smith snes->max_funcs = 10000; 17069b94acceSBarry Smith snes->norm = 0.0; 1707c1e67a49SFande Kong snes->xnorm = 0.0; 1708c1e67a49SFande Kong snes->ynorm = 0.0; 1709365a6726SPeter Brune snes->normschedule = SNES_NORM_ALWAYS; 17106c67d002SPeter Brune snes->functype = SNES_FUNCTION_DEFAULT; 17113a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 17123a2046daSBarry Smith snes->rtol = 1.e-5; 17133a2046daSBarry Smith #else 1714b4874afaSBarry Smith snes->rtol = 1.e-8; 17153a2046daSBarry Smith #endif 1716b4874afaSBarry Smith snes->ttol = 0.0; 17173a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 17183a2046daSBarry Smith snes->abstol = 1.e-25; 17193a2046daSBarry Smith #else 172070441072SBarry Smith snes->abstol = 1.e-50; 17213a2046daSBarry Smith #endif 17227cd0ae37SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE) 17237cd0ae37SLisandro Dalcin snes->stol = 1.e-5; 17247cd0ae37SLisandro Dalcin #else 1725c60f73f4SPeter Brune snes->stol = 1.e-8; 17267cd0ae37SLisandro Dalcin #endif 17273a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 17283a2046daSBarry Smith snes->deltatol = 1.e-6; 17293a2046daSBarry Smith #else 17304b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 17313a2046daSBarry Smith #endif 1732e37c518bSBarry Smith snes->divtol = 1.e4; 1733e37c518bSBarry Smith snes->rnorm0 = 0; 17349b94acceSBarry Smith snes->nfuncs = 0; 173550ffb88aSMatthew Knepley snes->numFailures = 0; 173650ffb88aSMatthew Knepley snes->maxFailures = 1; 17377a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1738e35cf81dSBarry Smith snes->lagjacobian = 1; 173937ec4e1aSPeter Brune snes->jac_iter = 0; 174037ec4e1aSPeter Brune snes->lagjac_persist = PETSC_FALSE; 1741a8054027SBarry Smith snes->lagpreconditioner = 1; 174237ec4e1aSPeter Brune snes->pre_iter = 0; 174337ec4e1aSPeter Brune snes->lagpre_persist = PETSC_FALSE; 1744639f9d9dSBarry Smith snes->numbermonitors = 0; 1745c4421ceaSFande Kong snes->numberreasonviews = 0; 17469e5d0892SLisandro Dalcin snes->data = NULL; 17474dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1748186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 17496f24a144SLois Curfman McInnes snes->nwork = 0; 17509e5d0892SLisandro Dalcin snes->work = NULL; 175158c9b817SLisandro Dalcin snes->nvwork = 0; 17529e5d0892SLisandro Dalcin snes->vwork = NULL; 1753758f92a0SBarry Smith snes->conv_hist_len = 0; 1754758f92a0SBarry Smith snes->conv_hist_max = 0; 17550298fd71SBarry Smith snes->conv_hist = NULL; 17560298fd71SBarry Smith snes->conv_hist_its = NULL; 1757758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1758971e163fSPeter Brune snes->counters_reset = PETSC_TRUE; 1759e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1760184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 1761efd4aadfSBarry Smith snes->npcside = PC_RIGHT; 1762b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled = 0; 1763c40d0f55SPeter Brune 1764d8f46077SPeter Brune snes->mf = PETSC_FALSE; 1765d8f46077SPeter Brune snes->mf_operator = PETSC_FALSE; 1766d8f46077SPeter Brune snes->mf_version = 1; 1767d8f46077SPeter Brune 17683d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 17693d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 17703d4c4710SBarry Smith 1771349187a7SBarry Smith snes->vizerotolerance = 1.e-8; 177276bd3646SJed Brown snes->checkjacdomainerror = PetscDefined(USE_DEBUG) ? PETSC_TRUE : PETSC_FALSE; 1773349187a7SBarry Smith 17744fc747eaSLawrence Mitchell /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */ 17754fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 17764fc747eaSLawrence Mitchell 17779b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 1778b00a9115SJed Brown ierr = PetscNewLog(snes,&kctx);CHKERRQ(ierr); 1779f5af7f23SKarl Rupp 17809b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 17819b94acceSBarry Smith kctx->version = 2; 17829b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 17839b94acceSBarry Smith this was too large for some test cases */ 178475567043SBarry Smith kctx->rtol_last = 0.0; 17859b94acceSBarry Smith kctx->rtol_max = .9; 17869b94acceSBarry Smith kctx->gamma = 1.0; 178762d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 178871f87433Sdalcinl kctx->alpha2 = kctx->alpha; 17899b94acceSBarry Smith kctx->threshold = .1; 179075567043SBarry Smith kctx->lresid_last = 0.0; 179175567043SBarry Smith kctx->norm_last = 0.0; 17929b94acceSBarry Smith 17939b94acceSBarry Smith *outsnes = snes; 17943a40ed3dSBarry Smith PetscFunctionReturn(0); 17959b94acceSBarry Smith } 17969b94acceSBarry Smith 179788f0584fSBarry Smith /*MC 1798411c0326SBarry Smith SNESFunction - Functional form used to convey the nonlinear function to be solved by SNES 179988f0584fSBarry Smith 180088f0584fSBarry Smith Synopsis: 1801411c0326SBarry Smith #include "petscsnes.h" 1802411c0326SBarry Smith PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx); 180388f0584fSBarry Smith 18041843f636SBarry Smith Collective on snes 18051843f636SBarry Smith 180688f0584fSBarry Smith Input Parameters: 180788f0584fSBarry Smith + snes - the SNES context 180888f0584fSBarry Smith . x - state at which to evaluate residual 180988f0584fSBarry Smith - ctx - optional user-defined function context, passed in with SNESSetFunction() 181088f0584fSBarry Smith 181188f0584fSBarry Smith Output Parameter: 181288f0584fSBarry Smith . f - vector to put residual (function value) 181388f0584fSBarry Smith 1814878cb397SSatish Balay Level: intermediate 1815878cb397SSatish Balay 181688f0584fSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 181788f0584fSBarry Smith M*/ 181888f0584fSBarry Smith 18199b94acceSBarry Smith /*@C 18209b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 18219b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 18229b94acceSBarry Smith equations. 18239b94acceSBarry Smith 18243f9fe445SBarry Smith Logically Collective on SNES 1825fee21e36SBarry Smith 1826c7afd0dbSLois Curfman McInnes Input Parameters: 1827c7afd0dbSLois Curfman McInnes + snes - the SNES context 1828c7afd0dbSLois Curfman McInnes . r - vector to store function value 1829f8b49ee9SBarry Smith . f - function evaluation routine; see SNESFunction for calling sequence details 1830c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 18310298fd71SBarry Smith function evaluation routine (may be NULL) 18329b94acceSBarry Smith 18339b94acceSBarry Smith Notes: 18349b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 18359b94acceSBarry Smith $ f'(x) x = -f(x), 1836c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 18379b94acceSBarry Smith 183836851e7fSLois Curfman McInnes Level: beginner 183936851e7fSLois Curfman McInnes 1840bf388a1fSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard(), SNESFunction 18419b94acceSBarry Smith @*/ 1842f8b49ee9SBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx) 18439b94acceSBarry Smith { 184485385478SLisandro Dalcin PetscErrorCode ierr; 18456cab3a1bSJed Brown DM dm; 18466cab3a1bSJed Brown 18473a40ed3dSBarry Smith PetscFunctionBegin; 18480700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1849d2a683ecSLisandro Dalcin if (r) { 1850d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1851d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 185285385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 18536bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 185485385478SLisandro Dalcin snes->vec_func = r; 1855d2a683ecSLisandro Dalcin } 18566cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1857f8b49ee9SBarry Smith ierr = DMSNESSetFunction(dm,f,ctx);CHKERRQ(ierr); 1858*bbc1464cSBarry Smith if (f == SNESPicardComputeFunction) { 1859*bbc1464cSBarry Smith ierr = DMSNESSetMFFunction(dm,SNESPicardComputeMFFunction,ctx);CHKERRQ(ierr); 1860*bbc1464cSBarry Smith } 18613a40ed3dSBarry Smith PetscFunctionReturn(0); 18629b94acceSBarry Smith } 18639b94acceSBarry Smith 1864646217ecSPeter Brune 1865e4ed7901SPeter Brune /*@C 1866e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1867e4ed7901SPeter Brune function norm at the initialization of the method. In some 1868e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1869e4ed7901SPeter Brune SNESSolve. This function allows one to avoid a redundant call 1870e4ed7901SPeter Brune to SNESComputeFunction in that case. 1871e4ed7901SPeter Brune 1872e4ed7901SPeter Brune Logically Collective on SNES 1873e4ed7901SPeter Brune 1874e4ed7901SPeter Brune Input Parameters: 1875e4ed7901SPeter Brune + snes - the SNES context 1876e4ed7901SPeter Brune - f - vector to store function value 1877e4ed7901SPeter Brune 1878e4ed7901SPeter Brune Notes: 1879e4ed7901SPeter Brune This should not be modified during the solution procedure. 1880e4ed7901SPeter Brune 1881e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1882e4ed7901SPeter Brune 1883e4ed7901SPeter Brune Level: developer 1884e4ed7901SPeter Brune 1885e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm() 1886e4ed7901SPeter Brune @*/ 1887e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1888e4ed7901SPeter Brune { 1889e4ed7901SPeter Brune PetscErrorCode ierr; 1890e4ed7901SPeter Brune Vec vec_func; 1891e4ed7901SPeter Brune 1892e4ed7901SPeter Brune PetscFunctionBegin; 1893e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1894e4ed7901SPeter Brune PetscValidHeaderSpecific(f,VEC_CLASSID,2); 1895e4ed7901SPeter Brune PetscCheckSameComm(snes,1,f,2); 1896efd4aadfSBarry Smith if (snes->npcside== PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) { 1897902f982fSPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1898902f982fSPeter Brune PetscFunctionReturn(0); 1899902f982fSPeter Brune } 19000298fd71SBarry Smith ierr = SNESGetFunction(snes,&vec_func,NULL,NULL);CHKERRQ(ierr); 1901e4ed7901SPeter Brune ierr = VecCopy(f, vec_func);CHKERRQ(ierr); 1902f5af7f23SKarl Rupp 1903217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 1904e4ed7901SPeter Brune PetscFunctionReturn(0); 1905e4ed7901SPeter Brune } 1906e4ed7901SPeter Brune 1907534ebe21SPeter Brune /*@ 1908365a6726SPeter Brune SNESSetNormSchedule - Sets the SNESNormSchedule used in covergence and monitoring 1909534ebe21SPeter Brune of the SNES method. 1910534ebe21SPeter Brune 1911534ebe21SPeter Brune Logically Collective on SNES 1912534ebe21SPeter Brune 1913534ebe21SPeter Brune Input Parameters: 1914534ebe21SPeter Brune + snes - the SNES context 1915365a6726SPeter Brune - normschedule - the frequency of norm computation 1916534ebe21SPeter Brune 1917517f1916SMatthew G. Knepley Options Database Key: 1918517f1916SMatthew G. Knepley . -snes_norm_schedule <none, always, initialonly, finalonly, initalfinalonly> 1919517f1916SMatthew G. Knepley 1920534ebe21SPeter Brune Notes: 1921365a6726SPeter Brune Only certain SNES methods support certain SNESNormSchedules. Most require evaluation 1922534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1923534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1924be95d8f1SBarry Smith (SNESNGS) and the like do not require the norm of the function to be computed, and therfore 1925534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1926534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1927534ebe21SPeter Brune their solution. 1928534ebe21SPeter Brune 1929534ebe21SPeter Brune Level: developer 1930534ebe21SPeter Brune 1931365a6726SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1932534ebe21SPeter Brune @*/ 1933365a6726SPeter Brune PetscErrorCode SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule) 1934534ebe21SPeter Brune { 1935534ebe21SPeter Brune PetscFunctionBegin; 1936534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1937365a6726SPeter Brune snes->normschedule = normschedule; 1938534ebe21SPeter Brune PetscFunctionReturn(0); 1939534ebe21SPeter Brune } 1940534ebe21SPeter Brune 1941534ebe21SPeter Brune 1942534ebe21SPeter Brune /*@ 1943365a6726SPeter Brune SNESGetNormSchedule - Gets the SNESNormSchedule used in covergence and monitoring 1944534ebe21SPeter Brune of the SNES method. 1945534ebe21SPeter Brune 1946534ebe21SPeter Brune Logically Collective on SNES 1947534ebe21SPeter Brune 1948534ebe21SPeter Brune Input Parameters: 1949534ebe21SPeter Brune + snes - the SNES context 1950365a6726SPeter Brune - normschedule - the type of the norm used 1951534ebe21SPeter Brune 1952534ebe21SPeter Brune Level: advanced 1953534ebe21SPeter Brune 1954365a6726SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1955534ebe21SPeter Brune @*/ 1956365a6726SPeter Brune PetscErrorCode SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule) 1957534ebe21SPeter Brune { 1958534ebe21SPeter Brune PetscFunctionBegin; 1959534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1960365a6726SPeter Brune *normschedule = snes->normschedule; 1961534ebe21SPeter Brune PetscFunctionReturn(0); 1962534ebe21SPeter Brune } 1963534ebe21SPeter Brune 196447073ea2SPeter Brune 1965c5ce4427SMatthew G. Knepley /*@ 1966c5ce4427SMatthew G. Knepley SNESSetFunctionNorm - Sets the last computed residual norm. 1967c5ce4427SMatthew G. Knepley 1968c5ce4427SMatthew G. Knepley Logically Collective on SNES 1969c5ce4427SMatthew G. Knepley 1970c5ce4427SMatthew G. Knepley Input Parameters: 1971c5ce4427SMatthew G. Knepley + snes - the SNES context 1972c5ce4427SMatthew G. Knepley 1973c5ce4427SMatthew G. Knepley - normschedule - the frequency of norm computation 1974c5ce4427SMatthew G. Knepley 1975c5ce4427SMatthew G. Knepley Level: developer 1976c5ce4427SMatthew G. Knepley 1977c5ce4427SMatthew G. Knepley .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1978c5ce4427SMatthew G. Knepley @*/ 1979c5ce4427SMatthew G. Knepley PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm) 1980c5ce4427SMatthew G. Knepley { 1981c5ce4427SMatthew G. Knepley PetscFunctionBegin; 1982c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1983c5ce4427SMatthew G. Knepley snes->norm = norm; 1984c5ce4427SMatthew G. Knepley PetscFunctionReturn(0); 1985c5ce4427SMatthew G. Knepley } 1986c5ce4427SMatthew G. Knepley 1987c5ce4427SMatthew G. Knepley /*@ 1988c5ce4427SMatthew G. Knepley SNESGetFunctionNorm - Gets the last computed norm of the residual 1989c5ce4427SMatthew G. Knepley 1990c5ce4427SMatthew G. Knepley Not Collective 1991c5ce4427SMatthew G. Knepley 1992c5ce4427SMatthew G. Knepley Input Parameter: 1993c5ce4427SMatthew G. Knepley . snes - the SNES context 1994c5ce4427SMatthew G. Knepley 1995c5ce4427SMatthew G. Knepley Output Parameter: 1996c5ce4427SMatthew G. Knepley . norm - the last computed residual norm 1997c5ce4427SMatthew G. Knepley 1998c5ce4427SMatthew G. Knepley Level: developer 1999c5ce4427SMatthew G. Knepley 2000c5ce4427SMatthew G. Knepley .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 2001c5ce4427SMatthew G. Knepley @*/ 2002c5ce4427SMatthew G. Knepley PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm) 2003c5ce4427SMatthew G. Knepley { 2004c5ce4427SMatthew G. Knepley PetscFunctionBegin; 2005c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2006c5ce4427SMatthew G. Knepley PetscValidPointer(norm, 2); 2007c5ce4427SMatthew G. Knepley *norm = snes->norm; 2008c5ce4427SMatthew G. Knepley PetscFunctionReturn(0); 2009c5ce4427SMatthew G. Knepley } 2010c5ce4427SMatthew G. Knepley 2011c1e67a49SFande Kong /*@ 2012c1e67a49SFande Kong SNESGetUpdateNorm - Gets the last computed norm of the Newton update 2013c1e67a49SFande Kong 2014c1e67a49SFande Kong Not Collective 2015c1e67a49SFande Kong 2016c1e67a49SFande Kong Input Parameter: 2017c1e67a49SFande Kong . snes - the SNES context 2018c1e67a49SFande Kong 2019c1e67a49SFande Kong Output Parameter: 2020c1e67a49SFande Kong . ynorm - the last computed update norm 2021c1e67a49SFande Kong 2022c1e67a49SFande Kong Level: developer 2023c1e67a49SFande Kong 2024c1e67a49SFande Kong .seealso: SNESSetNormSchedule(), SNESComputeFunction(), SNESGetFunctionNorm() 2025c1e67a49SFande Kong @*/ 2026c1e67a49SFande Kong PetscErrorCode SNESGetUpdateNorm(SNES snes, PetscReal *ynorm) 2027c1e67a49SFande Kong { 2028c1e67a49SFande Kong PetscFunctionBegin; 2029c1e67a49SFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2030c1e67a49SFande Kong PetscValidPointer(ynorm, 2); 2031c1e67a49SFande Kong *ynorm = snes->ynorm; 2032c1e67a49SFande Kong PetscFunctionReturn(0); 2033c1e67a49SFande Kong } 2034c1e67a49SFande Kong 2035c1e67a49SFande Kong /*@ 20364591eaf2SFande Kong SNESGetSolutionNorm - Gets the last computed norm of the solution 2037c1e67a49SFande Kong 2038c1e67a49SFande Kong Not Collective 2039c1e67a49SFande Kong 2040c1e67a49SFande Kong Input Parameter: 2041c1e67a49SFande Kong . snes - the SNES context 2042c1e67a49SFande Kong 2043c1e67a49SFande Kong Output Parameter: 2044c1e67a49SFande Kong . xnorm - the last computed solution norm 2045c1e67a49SFande Kong 2046c1e67a49SFande Kong Level: developer 2047c1e67a49SFande Kong 2048c1e67a49SFande Kong .seealso: SNESSetNormSchedule(), SNESComputeFunction(), SNESGetFunctionNorm(), SNESGetUpdateNorm() 2049c1e67a49SFande Kong @*/ 2050c1e67a49SFande Kong PetscErrorCode SNESGetSolutionNorm(SNES snes, PetscReal *xnorm) 2051c1e67a49SFande Kong { 2052c1e67a49SFande Kong PetscFunctionBegin; 2053c1e67a49SFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2054c1e67a49SFande Kong PetscValidPointer(xnorm, 2); 2055c1e67a49SFande Kong *xnorm = snes->xnorm; 2056c1e67a49SFande Kong PetscFunctionReturn(0); 2057c1e67a49SFande Kong } 2058c1e67a49SFande Kong 205947073ea2SPeter Brune /*@C 206047073ea2SPeter Brune SNESSetFunctionType - Sets the SNESNormSchedule used in covergence and monitoring 206147073ea2SPeter Brune of the SNES method. 206247073ea2SPeter Brune 206347073ea2SPeter Brune Logically Collective on SNES 206447073ea2SPeter Brune 206547073ea2SPeter Brune Input Parameters: 206647073ea2SPeter Brune + snes - the SNES context 206747073ea2SPeter Brune - normschedule - the frequency of norm computation 206847073ea2SPeter Brune 206947073ea2SPeter Brune Notes: 207047073ea2SPeter Brune Only certain SNES methods support certain SNESNormSchedules. Most require evaluation 207147073ea2SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 207247073ea2SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 2073be95d8f1SBarry Smith (SNESNGS) and the like do not require the norm of the function to be computed, and therfore 207447073ea2SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 207547073ea2SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 207647073ea2SPeter Brune their solution. 207747073ea2SPeter Brune 207847073ea2SPeter Brune Level: developer 207947073ea2SPeter Brune 208047073ea2SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 208147073ea2SPeter Brune @*/ 208247073ea2SPeter Brune PetscErrorCode SNESSetFunctionType(SNES snes, SNESFunctionType type) 208347073ea2SPeter Brune { 208447073ea2SPeter Brune PetscFunctionBegin; 208547073ea2SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 208647073ea2SPeter Brune snes->functype = type; 208747073ea2SPeter Brune PetscFunctionReturn(0); 208847073ea2SPeter Brune } 208947073ea2SPeter Brune 209047073ea2SPeter Brune 209147073ea2SPeter Brune /*@C 209247073ea2SPeter Brune SNESGetFunctionType - Gets the SNESNormSchedule used in covergence and monitoring 209347073ea2SPeter Brune of the SNES method. 209447073ea2SPeter Brune 209547073ea2SPeter Brune Logically Collective on SNES 209647073ea2SPeter Brune 209747073ea2SPeter Brune Input Parameters: 209847073ea2SPeter Brune + snes - the SNES context 209947073ea2SPeter Brune - normschedule - the type of the norm used 210047073ea2SPeter Brune 210147073ea2SPeter Brune Level: advanced 210247073ea2SPeter Brune 210347073ea2SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 210447073ea2SPeter Brune @*/ 210547073ea2SPeter Brune PetscErrorCode SNESGetFunctionType(SNES snes, SNESFunctionType *type) 210647073ea2SPeter Brune { 210747073ea2SPeter Brune PetscFunctionBegin; 210847073ea2SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 210947073ea2SPeter Brune *type = snes->functype; 2110534ebe21SPeter Brune PetscFunctionReturn(0); 2111534ebe21SPeter Brune } 2112534ebe21SPeter Brune 2113bf388a1fSBarry Smith /*MC 2114be95d8f1SBarry Smith SNESNGSFunction - function used to convey a Gauss-Seidel sweep on the nonlinear function 2115bf388a1fSBarry Smith 2116bf388a1fSBarry Smith Synopsis: 2117aaa7dc30SBarry Smith #include <petscsnes.h> 2118be95d8f1SBarry Smith $ SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx); 2119bf388a1fSBarry Smith 21201843f636SBarry Smith Collective on snes 21211843f636SBarry Smith 21221843f636SBarry Smith Input Parameters: 2123bf388a1fSBarry Smith + X - solution vector 2124bf388a1fSBarry Smith . B - RHS vector 2125bf388a1fSBarry Smith - ctx - optional user-defined Gauss-Seidel context 2126bf388a1fSBarry Smith 21271843f636SBarry Smith Output Parameter: 21281843f636SBarry Smith . X - solution vector 21291843f636SBarry Smith 2130878cb397SSatish Balay Level: intermediate 2131878cb397SSatish Balay 2132be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESGetNGS() 2133bf388a1fSBarry Smith M*/ 2134bf388a1fSBarry Smith 2135c79ef259SPeter Brune /*@C 2136be95d8f1SBarry Smith SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for 2137c79ef259SPeter Brune use with composed nonlinear solvers. 2138c79ef259SPeter Brune 2139c79ef259SPeter Brune Input Parameters: 2140c79ef259SPeter Brune + snes - the SNES context 2141be95d8f1SBarry Smith . f - function evaluation routine to apply Gauss-Seidel see SNESNGSFunction 2142c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 21430298fd71SBarry Smith smoother evaluation routine (may be NULL) 2144c79ef259SPeter Brune 2145c79ef259SPeter Brune Notes: 2146be95d8f1SBarry Smith The NGS routines are used by the composed nonlinear solver to generate 2147c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 2148c79ef259SPeter Brune 2149d28543b3SPeter Brune Level: intermediate 2150c79ef259SPeter Brune 2151be95d8f1SBarry Smith .seealso: SNESGetFunction(), SNESComputeNGS() 2152c79ef259SPeter Brune @*/ 2153be95d8f1SBarry Smith PetscErrorCode SNESSetNGS(SNES snes,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx) 21546cab3a1bSJed Brown { 21556cab3a1bSJed Brown PetscErrorCode ierr; 21566cab3a1bSJed Brown DM dm; 21576cab3a1bSJed Brown 2158646217ecSPeter Brune PetscFunctionBegin; 21596cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 21606cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2161be95d8f1SBarry Smith ierr = DMSNESSetNGS(dm,f,ctx);CHKERRQ(ierr); 2162646217ecSPeter Brune PetscFunctionReturn(0); 2163646217ecSPeter Brune } 2164646217ecSPeter Brune 2165*bbc1464cSBarry Smith /* 2166*bbc1464cSBarry Smith This is used for -snes_mf_operator; it uses a duplicate of snes->jacobian_pre because snes->jacobian_pre cannot be 2167*bbc1464cSBarry Smith changed during the KSPSolve() 2168*bbc1464cSBarry Smith */ 2169*bbc1464cSBarry Smith PetscErrorCode SNESPicardComputeMFFunction(SNES snes,Vec x,Vec f,void *ctx) 2170*bbc1464cSBarry Smith { 2171*bbc1464cSBarry Smith PetscErrorCode ierr; 2172*bbc1464cSBarry Smith DM dm; 2173*bbc1464cSBarry Smith DMSNES sdm; 2174*bbc1464cSBarry Smith 2175*bbc1464cSBarry Smith PetscFunctionBegin; 2176*bbc1464cSBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2177*bbc1464cSBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 2178*bbc1464cSBarry Smith if (!sdm->ops->computepjacobian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard Jacobian."); 2179*bbc1464cSBarry Smith /* A(x)*x - b(x) */ 2180*bbc1464cSBarry Smith if (sdm->ops->computepfunction) { 2181*bbc1464cSBarry Smith PetscStackPush("SNES Picard user function"); 2182*bbc1464cSBarry Smith ierr = (*sdm->ops->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr); 2183*bbc1464cSBarry Smith PetscStackPop; 2184*bbc1464cSBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 2185*bbc1464cSBarry Smith if (!snes->picard) { 2186*bbc1464cSBarry Smith ierr = MatDuplicate(snes->jacobian_pre,MAT_SHARE_NONZERO_PATTERN,&snes->picard);CHKERRQ(ierr); 2187*bbc1464cSBarry Smith } 2188*bbc1464cSBarry Smith PetscStackPush("SNES Picard user Jacobian"); 2189*bbc1464cSBarry Smith ierr = (*sdm->ops->computepjacobian)(snes,x,snes->picard,snes->picard,sdm->pctx);CHKERRQ(ierr); 2190*bbc1464cSBarry Smith PetscStackPop; 2191*bbc1464cSBarry Smith ierr = MatMultAdd(snes->picard,x,f,f);CHKERRQ(ierr); 2192*bbc1464cSBarry Smith } else { 2193*bbc1464cSBarry Smith PetscStackPush("SNES Picard user Jacobian"); 2194*bbc1464cSBarry Smith ierr = (*sdm->ops->computepjacobian)(snes,x,snes->picard,snes->picard,sdm->pctx);CHKERRQ(ierr); 2195*bbc1464cSBarry Smith PetscStackPop; 2196*bbc1464cSBarry Smith ierr = MatMult(snes->picard,x,f);CHKERRQ(ierr); 2197*bbc1464cSBarry Smith } 2198*bbc1464cSBarry Smith PetscFunctionReturn(0); 2199*bbc1464cSBarry Smith } 2200*bbc1464cSBarry Smith 220125acbd8eSLisandro Dalcin PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 22028b0a5094SBarry Smith { 22038b0a5094SBarry Smith PetscErrorCode ierr; 2204e03ab78fSPeter Brune DM dm; 2205942e3340SBarry Smith DMSNES sdm; 22066cab3a1bSJed Brown 22078b0a5094SBarry Smith PetscFunctionBegin; 2208e03ab78fSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2209942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 221025acbd8eSLisandro Dalcin if (!sdm->ops->computepjacobian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard Jacobian."); 22118b0a5094SBarry Smith /* A(x)*x - b(x) */ 2212*bbc1464cSBarry Smith if (sdm->ops->computepfunction){ 221325acbd8eSLisandro Dalcin PetscStackPush("SNES Picard user function"); 221422c6f798SBarry Smith ierr = (*sdm->ops->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr); 221525acbd8eSLisandro Dalcin PetscStackPop; 2216*bbc1464cSBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 221725acbd8eSLisandro Dalcin PetscStackPush("SNES Picard user Jacobian"); 2218d1e9a80fSBarry Smith ierr = (*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx);CHKERRQ(ierr); 221925acbd8eSLisandro Dalcin PetscStackPop; 2220*bbc1464cSBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 2221*bbc1464cSBarry Smith } else { 2222*bbc1464cSBarry Smith PetscStackPush("SNES Picard user Jacobian"); 2223*bbc1464cSBarry Smith ierr = (*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx);CHKERRQ(ierr); 2224*bbc1464cSBarry Smith PetscStackPop; 2225*bbc1464cSBarry Smith ierr = MatMult(snes->jacobian_pre,x,f);CHKERRQ(ierr); 2226*bbc1464cSBarry Smith } 22278b0a5094SBarry Smith PetscFunctionReturn(0); 22288b0a5094SBarry Smith } 22298b0a5094SBarry Smith 223025acbd8eSLisandro Dalcin PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat J,Mat B,void *ctx) 22318b0a5094SBarry Smith { 2232*bbc1464cSBarry Smith PetscErrorCode ierr; 22338b0a5094SBarry Smith PetscFunctionBegin; 2234e03ab78fSPeter Brune /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */ 2235*bbc1464cSBarry Smith /* must assembly if matrix-free to get the last SNES solution */ 2236*bbc1464cSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2237*bbc1464cSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 22388b0a5094SBarry Smith PetscFunctionReturn(0); 22398b0a5094SBarry Smith } 22408b0a5094SBarry Smith 22418b0a5094SBarry Smith /*@C 2242*bbc1464cSBarry Smith SNESSetPicard - Use SNES to solve the system A(x) x = bp(x) + b via a Picard type iteration (Picard linearization) 22438b0a5094SBarry Smith 22448b0a5094SBarry Smith Logically Collective on SNES 22458b0a5094SBarry Smith 22468b0a5094SBarry Smith Input Parameters: 22478b0a5094SBarry Smith + snes - the SNES context 22488b0a5094SBarry Smith . r - vector to store function value 2249*bbc1464cSBarry Smith . bp - function evaluation routine 2250e5d3d808SBarry Smith . Amat - matrix with which A(x) x - b(x) is to be computed 2251e5d3d808SBarry Smith . Pmat - matrix from which preconditioner is computed (usually the same as Amat) 2252411c0326SBarry Smith . J - function to compute matrix value, see SNESJacobianFunction for details on its calling sequence 22538b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 22540298fd71SBarry Smith function evaluation routine (may be NULL) 22558b0a5094SBarry Smith 22568b0a5094SBarry Smith Notes: 2257f450aa47SBarry Smith We do not recomemend using this routine. It is far better to provide the nonlinear function F() and some approximation to the Jacobian and use 2258f450aa47SBarry 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. 2259f450aa47SBarry Smith 22608b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 22618b0a5094SBarry Smith 22628b0a5094SBarry Smith $ Solves the equation A(x) x = b(x) via the defect correction algorithm A(x^{n}) (x^{n+1} - x^{n}) = b(x^{n}) - A(x^{n})x^{n} 22638b0a5094SBarry Smith $ Note that when an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = b(x^{n}) iteration. 22648b0a5094SBarry Smith 22658b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 22668b0a5094SBarry Smith 22670d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 22680d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 22698b0a5094SBarry Smith 22708b0a5094SBarry 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 22718b0a5094SBarry 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 22728b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 22738b0a5094SBarry Smith 2274*bbc1464cSBarry 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 - b(x). 2275*bbc1464cSBarry Smith 2276f450aa47SBarry Smith Level: intermediate 22778b0a5094SBarry Smith 2278411c0326SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard(), SNESJacobianFunction 22798b0a5094SBarry Smith @*/ 2280*bbc1464cSBarry 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) 22818b0a5094SBarry Smith { 22828b0a5094SBarry Smith PetscErrorCode ierr; 2283e03ab78fSPeter Brune DM dm; 2284e03ab78fSPeter Brune 22858b0a5094SBarry Smith PetscFunctionBegin; 22868b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2287e03ab78fSPeter Brune ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 2288*bbc1464cSBarry Smith ierr = DMSNESSetPicard(dm,bp,J,ctx);CHKERRQ(ierr); 2289*bbc1464cSBarry Smith ierr = DMSNESSetMFFunction(dm,SNESPicardComputeMFFunction,ctx);CHKERRQ(ierr); 22908b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 2291e5d3d808SBarry Smith ierr = SNESSetJacobian(snes,Amat,Pmat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 22928b0a5094SBarry Smith PetscFunctionReturn(0); 22938b0a5094SBarry Smith } 22948b0a5094SBarry Smith 22957971a8bfSPeter Brune /*@C 22967971a8bfSPeter Brune SNESGetPicard - Returns the context for the Picard iteration 22977971a8bfSPeter Brune 22987971a8bfSPeter Brune Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 22997971a8bfSPeter Brune 23007971a8bfSPeter Brune Input Parameter: 23017971a8bfSPeter Brune . snes - the SNES context 23027971a8bfSPeter Brune 23037971a8bfSPeter Brune Output Parameter: 23040298fd71SBarry Smith + r - the function (or NULL) 2305f8b49ee9SBarry Smith . f - the function (or NULL); see SNESFunction for calling sequence details 2306e4357dc4SBarry Smith . Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL) 2307e4357dc4SBarry Smith . Pmat - the matrix from which the preconditioner will be constructed (or NULL) 2308f8b49ee9SBarry Smith . J - the function for matrix evaluation (or NULL); see SNESJacobianFunction for calling sequence details 23090298fd71SBarry Smith - ctx - the function context (or NULL) 23107971a8bfSPeter Brune 23117971a8bfSPeter Brune Level: advanced 23127971a8bfSPeter Brune 2313e4357dc4SBarry Smith .seealso: SNESSetPicard(), SNESGetFunction(), SNESGetJacobian(), SNESGetDM(), SNESFunction, SNESJacobianFunction 23147971a8bfSPeter Brune @*/ 2315d1e9a80fSBarry 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) 23167971a8bfSPeter Brune { 23177971a8bfSPeter Brune PetscErrorCode ierr; 23187971a8bfSPeter Brune DM dm; 23197971a8bfSPeter Brune 23207971a8bfSPeter Brune PetscFunctionBegin; 23217971a8bfSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23220298fd71SBarry Smith ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 2323e4357dc4SBarry Smith ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 23247971a8bfSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2325f8b49ee9SBarry Smith ierr = DMSNESGetPicard(dm,f,J,ctx);CHKERRQ(ierr); 23267971a8bfSPeter Brune PetscFunctionReturn(0); 23277971a8bfSPeter Brune } 23287971a8bfSPeter Brune 2329d25893d9SBarry Smith /*@C 2330d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 2331d25893d9SBarry Smith 2332d25893d9SBarry Smith Logically Collective on SNES 2333d25893d9SBarry Smith 2334d25893d9SBarry Smith Input Parameters: 2335d25893d9SBarry Smith + snes - the SNES context 2336d25893d9SBarry Smith . func - function evaluation routine 2337d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 23380298fd71SBarry Smith function evaluation routine (may be NULL) 2339d25893d9SBarry Smith 2340d25893d9SBarry Smith Calling sequence of func: 2341d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 2342d25893d9SBarry Smith 2343d25893d9SBarry Smith . f - function vector 2344d25893d9SBarry Smith - ctx - optional user-defined function context 2345d25893d9SBarry Smith 2346d25893d9SBarry Smith Level: intermediate 2347d25893d9SBarry Smith 2348d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 2349d25893d9SBarry Smith @*/ 2350d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 2351d25893d9SBarry Smith { 2352d25893d9SBarry Smith PetscFunctionBegin; 2353d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2354d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 2355d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 2356d25893d9SBarry Smith PetscFunctionReturn(0); 2357d25893d9SBarry Smith } 2358d25893d9SBarry Smith 23593ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 23601096aae1SMatthew Knepley /*@C 23611096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 23621096aae1SMatthew Knepley it assumes a zero right hand side. 23631096aae1SMatthew Knepley 23643f9fe445SBarry Smith Logically Collective on SNES 23651096aae1SMatthew Knepley 23661096aae1SMatthew Knepley Input Parameter: 23671096aae1SMatthew Knepley . snes - the SNES context 23681096aae1SMatthew Knepley 23691096aae1SMatthew Knepley Output Parameter: 23700298fd71SBarry Smith . rhs - the right hand side vector or NULL if the right hand side vector is null 23711096aae1SMatthew Knepley 23721096aae1SMatthew Knepley Level: intermediate 23731096aae1SMatthew Knepley 237485385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 23751096aae1SMatthew Knepley @*/ 23767087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 23771096aae1SMatthew Knepley { 23781096aae1SMatthew Knepley PetscFunctionBegin; 23790700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23801096aae1SMatthew Knepley PetscValidPointer(rhs,2); 238185385478SLisandro Dalcin *rhs = snes->vec_rhs; 23821096aae1SMatthew Knepley PetscFunctionReturn(0); 23831096aae1SMatthew Knepley } 23841096aae1SMatthew Knepley 23859b94acceSBarry Smith /*@ 2386bf388a1fSBarry Smith SNESComputeFunction - Calls the function that has been set with SNESSetFunction(). 23879b94acceSBarry Smith 2388c7afd0dbSLois Curfman McInnes Collective on SNES 2389c7afd0dbSLois Curfman McInnes 23909b94acceSBarry Smith Input Parameters: 2391c7afd0dbSLois Curfman McInnes + snes - the SNES context 2392c7afd0dbSLois Curfman McInnes - x - input vector 23939b94acceSBarry Smith 23949b94acceSBarry Smith Output Parameter: 23953638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 23969b94acceSBarry Smith 23971bffabb2SLois Curfman McInnes Notes: 239836851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 2399*bbc1464cSBarry Smith implementations, so users would not generally call this routine themselves. 240036851e7fSLois Curfman McInnes 240136851e7fSLois Curfman McInnes Level: developer 240236851e7fSLois Curfman McInnes 2403*bbc1464cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction(), SNESComputeMFFunction() 24049b94acceSBarry Smith @*/ 24057087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 24069b94acceSBarry Smith { 2407dfbe8321SBarry Smith PetscErrorCode ierr; 24086cab3a1bSJed Brown DM dm; 2409942e3340SBarry Smith DMSNES sdm; 24109b94acceSBarry Smith 24113a40ed3dSBarry Smith PetscFunctionBegin; 24120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 24130700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 24140700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2415c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 2416c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 241762796dfbSBarry Smith ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr); 2418184914b5SBarry Smith 24196cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2420942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 242132f3f7c2SPeter Brune if (sdm->ops->computefunction) { 242294db00ebSBarry Smith if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) { 2423ccf3c845SPeter Brune ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 242494db00ebSBarry Smith } 24258860a134SJunchao Zhang ierr = VecLockReadPush(x);CHKERRQ(ierr); 2426d64ed03dSBarry Smith PetscStackPush("SNES user function"); 24278ddeebeaSSteve Benbow /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 24288ddeebeaSSteve Benbow snes->domainerror = PETSC_FALSE; 242922c6f798SBarry Smith ierr = (*sdm->ops->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 2430d64ed03dSBarry Smith PetscStackPop; 24318860a134SJunchao Zhang ierr = VecLockReadPop(x);CHKERRQ(ierr); 243294db00ebSBarry Smith if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) { 2433ccf3c845SPeter Brune ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 243494db00ebSBarry Smith } 2435c90fad12SPeter Brune } else if (snes->vec_rhs) { 2436c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 2437644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 243885385478SLisandro Dalcin if (snes->vec_rhs) { 243985385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 24403ab0aad5SBarry Smith } 2441ae3c334cSLois Curfman McInnes snes->nfuncs++; 2442422a814eSBarry Smith /* 2443422a814eSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2444422a814eSBarry Smith propagate the value to all processes 2445422a814eSBarry Smith */ 2446422a814eSBarry Smith if (snes->domainerror) { 2447422a814eSBarry Smith ierr = VecSetInf(y);CHKERRQ(ierr); 2448422a814eSBarry Smith } 24493a40ed3dSBarry Smith PetscFunctionReturn(0); 24509b94acceSBarry Smith } 24519b94acceSBarry Smith 2452c79ef259SPeter Brune /*@ 2453*bbc1464cSBarry Smith SNESComputeMFFunction - Calls the function that has been set with SNESSetMFFunction(). 2454*bbc1464cSBarry Smith 2455*bbc1464cSBarry Smith Collective on SNES 2456*bbc1464cSBarry Smith 2457*bbc1464cSBarry Smith Input Parameters: 2458*bbc1464cSBarry Smith + snes - the SNES context 2459*bbc1464cSBarry Smith - x - input vector 2460*bbc1464cSBarry Smith 2461*bbc1464cSBarry Smith Output Parameter: 2462*bbc1464cSBarry Smith . y - function vector, as set by SNESSetMFFunction() 2463*bbc1464cSBarry Smith 2464*bbc1464cSBarry Smith Notes: 2465*bbc1464cSBarry Smith SNESComputeMFFunction() is used within the matrix vector products called by the matrix created with MatCreateSNESMF() 2466*bbc1464cSBarry Smith so users would not generally call this routine themselves. 2467*bbc1464cSBarry Smith 2468*bbc1464cSBarry Smith Since this function is intended for use with finite differencing it does not subtract the right hand side vector provided with SNESSolve() 2469*bbc1464cSBarry Smith while SNESComputeFunction() does. As such, this routine cannot be used with MatMFFDSetBase() with a provided F function value even if it applies the 2470*bbc1464cSBarry 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. 2471*bbc1464cSBarry Smith 2472*bbc1464cSBarry Smith Level: developer 2473*bbc1464cSBarry Smith 2474*bbc1464cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction(), SNESComputeFunction(), MatCreateSNESMF 2475*bbc1464cSBarry Smith @*/ 2476*bbc1464cSBarry Smith PetscErrorCode SNESComputeMFFunction(SNES snes,Vec x,Vec y) 2477*bbc1464cSBarry Smith { 2478*bbc1464cSBarry Smith PetscErrorCode ierr; 2479*bbc1464cSBarry Smith DM dm; 2480*bbc1464cSBarry Smith DMSNES sdm; 2481*bbc1464cSBarry Smith 2482*bbc1464cSBarry Smith PetscFunctionBegin; 2483*bbc1464cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2484*bbc1464cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2485*bbc1464cSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2486*bbc1464cSBarry Smith PetscCheckSameComm(snes,1,x,2); 2487*bbc1464cSBarry Smith PetscCheckSameComm(snes,1,y,3); 2488*bbc1464cSBarry Smith ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr); 2489*bbc1464cSBarry Smith 2490*bbc1464cSBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2491*bbc1464cSBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 2492*bbc1464cSBarry Smith ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 2493*bbc1464cSBarry Smith ierr = VecLockReadPush(x);CHKERRQ(ierr); 2494*bbc1464cSBarry Smith PetscStackPush("SNES user function"); 2495*bbc1464cSBarry Smith /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 2496*bbc1464cSBarry Smith snes->domainerror = PETSC_FALSE; 2497*bbc1464cSBarry Smith ierr = (*sdm->ops->computemffunction)(snes,x,y,sdm->mffunctionctx);CHKERRQ(ierr); 2498*bbc1464cSBarry Smith PetscStackPop; 2499*bbc1464cSBarry Smith ierr = VecLockReadPop(x);CHKERRQ(ierr); 2500*bbc1464cSBarry Smith ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 2501*bbc1464cSBarry Smith snes->nfuncs++; 2502*bbc1464cSBarry Smith /* 2503*bbc1464cSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2504*bbc1464cSBarry Smith propagate the value to all processes 2505*bbc1464cSBarry Smith */ 2506*bbc1464cSBarry Smith if (snes->domainerror) { 2507*bbc1464cSBarry Smith ierr = VecSetInf(y);CHKERRQ(ierr); 2508*bbc1464cSBarry Smith } 2509*bbc1464cSBarry Smith PetscFunctionReturn(0); 2510*bbc1464cSBarry Smith } 2511*bbc1464cSBarry Smith 2512*bbc1464cSBarry Smith /*@ 2513be95d8f1SBarry Smith SNESComputeNGS - Calls the Gauss-Seidel function that has been set with SNESSetNGS(). 2514c79ef259SPeter Brune 2515c79ef259SPeter Brune Collective on SNES 2516c79ef259SPeter Brune 2517c79ef259SPeter Brune Input Parameters: 2518c79ef259SPeter Brune + snes - the SNES context 2519c79ef259SPeter Brune . x - input vector 2520c79ef259SPeter Brune - b - rhs vector 2521c79ef259SPeter Brune 2522c79ef259SPeter Brune Output Parameter: 2523c79ef259SPeter Brune . x - new solution vector 2524c79ef259SPeter Brune 2525c79ef259SPeter Brune Notes: 2526be95d8f1SBarry Smith SNESComputeNGS() is typically used within composed nonlinear solver 2527c79ef259SPeter Brune implementations, so most users would not generally call this routine 2528c79ef259SPeter Brune themselves. 2529c79ef259SPeter Brune 2530c79ef259SPeter Brune Level: developer 2531c79ef259SPeter Brune 2532be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESComputeFunction() 2533c79ef259SPeter Brune @*/ 2534be95d8f1SBarry Smith PetscErrorCode SNESComputeNGS(SNES snes,Vec b,Vec x) 2535646217ecSPeter Brune { 2536646217ecSPeter Brune PetscErrorCode ierr; 25376cab3a1bSJed Brown DM dm; 2538942e3340SBarry Smith DMSNES sdm; 2539646217ecSPeter Brune 2540646217ecSPeter Brune PetscFunctionBegin; 2541646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2542646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2543646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 2544646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 2545646217ecSPeter Brune if (b) PetscCheckSameComm(snes,1,b,3); 254662796dfbSBarry Smith if (b) {ierr = VecValidValues(b,2,PETSC_TRUE);CHKERRQ(ierr);} 2547be95d8f1SBarry Smith ierr = PetscLogEventBegin(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr); 25486cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2549942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 255022c6f798SBarry Smith if (sdm->ops->computegs) { 25518860a134SJunchao Zhang if (b) {ierr = VecLockReadPush(b);CHKERRQ(ierr);} 2552be95d8f1SBarry Smith PetscStackPush("SNES user NGS"); 255322c6f798SBarry Smith ierr = (*sdm->ops->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 2554646217ecSPeter Brune PetscStackPop; 25558860a134SJunchao Zhang if (b) {ierr = VecLockReadPop(b);CHKERRQ(ierr);} 2556be95d8f1SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve()."); 2557be95d8f1SBarry Smith ierr = PetscLogEventEnd(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr); 2558646217ecSPeter Brune PetscFunctionReturn(0); 2559646217ecSPeter Brune } 2560646217ecSPeter Brune 2561e885f1abSBarry Smith PetscErrorCode SNESTestJacobian(SNES snes) 2562e885f1abSBarry Smith { 256312837594SBarry Smith Mat A,B,C,D,jacobian; 2564e885f1abSBarry Smith Vec x = snes->vec_sol,f = snes->vec_func; 2565e885f1abSBarry Smith PetscErrorCode ierr; 2566e885f1abSBarry Smith PetscReal nrm,gnorm; 256781e7118cSBarry Smith PetscReal threshold = 1.e-5; 25680e276705SLisandro Dalcin MatType mattype; 2569e885f1abSBarry Smith PetscInt m,n,M,N; 2570e885f1abSBarry Smith void *functx; 25712cd624f9SStefano Zampini PetscBool complete_print = PETSC_FALSE,threshold_print = PETSC_FALSE,test = PETSC_FALSE,flg,istranspose; 25723325ff46SBarry Smith PetscViewer viewer,mviewer; 2573e885f1abSBarry Smith MPI_Comm comm; 2574e885f1abSBarry Smith PetscInt tabs; 257512837594SBarry Smith static PetscBool directionsprinted = PETSC_FALSE; 25763325ff46SBarry Smith PetscViewerFormat format; 2577e885f1abSBarry Smith 2578e885f1abSBarry Smith PetscFunctionBegin; 2579fc35ed60SBarry Smith ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 258012837594SBarry Smith ierr = PetscOptionsName("-snes_test_jacobian","Compare hand-coded and finite difference Jacobians","None",&test);CHKERRQ(ierr); 258112837594SBarry Smith ierr = PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold,NULL);CHKERRQ(ierr); 25823325ff46SBarry 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); 258318d89885SKarl Rupp if (!complete_print) { 2584455a5933SJed Brown ierr = PetscOptionsDeprecated("-snes_test_jacobian_display","-snes_test_jacobian_view","3.13",NULL);CHKERRQ(ierr); 258518d89885SKarl Rupp ierr = PetscOptionsViewer("-snes_test_jacobian_display","Display difference between hand-coded and finite difference Jacobians","None",&mviewer,&format,&complete_print);CHKERRQ(ierr); 258618d89885SKarl Rupp } 258718d89885SKarl Rupp /* for compatibility with PETSc 3.9 and older. */ 2588455a5933SJed 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); 258918d89885SKarl 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); 2590e885f1abSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 2591e885f1abSBarry Smith if (!test) PetscFunctionReturn(0); 2592e885f1abSBarry Smith 2593e885f1abSBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2594e885f1abSBarry Smith ierr = PetscViewerASCIIGetStdout(comm,&viewer);CHKERRQ(ierr); 2595e885f1abSBarry Smith ierr = PetscViewerASCIIGetTab(viewer, &tabs);CHKERRQ(ierr); 2596e885f1abSBarry Smith ierr = PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel);CHKERRQ(ierr); 259712837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," ---------- Testing Jacobian -------------\n");CHKERRQ(ierr); 259812837594SBarry Smith if (!complete_print && !directionsprinted) { 259912837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n");CHKERRQ(ierr); 2600fc35ed60SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," of hand-coded and finite difference Jacobian entries greater than <threshold>.\n");CHKERRQ(ierr); 260112837594SBarry Smith } 260212837594SBarry Smith if (!directionsprinted) { 260312837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n");CHKERRQ(ierr); 2604e885f1abSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," O(1.e-8), the hand-coded Jacobian is probably correct.\n");CHKERRQ(ierr); 260512837594SBarry Smith directionsprinted = PETSC_TRUE; 2606e885f1abSBarry Smith } 26073325ff46SBarry Smith if (complete_print) { 26083325ff46SBarry Smith ierr = PetscViewerPushFormat(mviewer,format);CHKERRQ(ierr); 2609e885f1abSBarry Smith } 2610e885f1abSBarry Smith 261112837594SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)snes->jacobian,MATMFFD,&flg);CHKERRQ(ierr); 261212837594SBarry Smith if (!flg) jacobian = snes->jacobian; 261312837594SBarry Smith else jacobian = snes->jacobian_pre; 261412837594SBarry Smith 2615a82339d0SMatthew G. Knepley if (!x) { 2616a82339d0SMatthew G. Knepley ierr = MatCreateVecs(jacobian, &x, NULL);CHKERRQ(ierr); 2617a82339d0SMatthew G. Knepley } else { 2618a82339d0SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) x);CHKERRQ(ierr); 2619a82339d0SMatthew G. Knepley } 2620a82339d0SMatthew G. Knepley if (!f) { 2621a82339d0SMatthew G. Knepley ierr = VecDuplicate(x, &f);CHKERRQ(ierr); 2622a82339d0SMatthew G. Knepley } else { 2623a82339d0SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) f);CHKERRQ(ierr); 2624a82339d0SMatthew G. Knepley } 2625a82339d0SMatthew G. Knepley /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */ 2626a82339d0SMatthew G. Knepley ierr = SNESComputeFunction(snes,x,f);CHKERRQ(ierr); 2627a82339d0SMatthew G. Knepley ierr = VecDestroy(&f);CHKERRQ(ierr); 26282cd624f9SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)snes,SNESKSPTRANSPOSEONLY,&istranspose);CHKERRQ(ierr); 262912837594SBarry Smith while (jacobian) { 26302cd624f9SStefano Zampini Mat JT = NULL, Jsave = NULL; 26312cd624f9SStefano Zampini 26322cd624f9SStefano Zampini if (istranspose) { 26332cd624f9SStefano Zampini ierr = MatCreateTranspose(jacobian,&JT);CHKERRQ(ierr); 26342cd624f9SStefano Zampini Jsave = jacobian; 26352cd624f9SStefano Zampini jacobian = JT; 26362cd624f9SStefano Zampini } 26370e276705SLisandro Dalcin ierr = PetscObjectBaseTypeCompareAny((PetscObject)jacobian,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPISBAIJ,"");CHKERRQ(ierr); 263812837594SBarry Smith if (flg) { 263912837594SBarry Smith A = jacobian; 264012837594SBarry Smith ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 264112837594SBarry Smith } else { 26420bacdadaSStefano Zampini ierr = MatComputeOperator(jacobian,MATAIJ,&A);CHKERRQ(ierr); 264312837594SBarry Smith } 2644e885f1abSBarry Smith 26450e276705SLisandro Dalcin ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 2646e885f1abSBarry Smith ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 2647e885f1abSBarry Smith ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 26480e276705SLisandro Dalcin ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr); 26490e276705SLisandro Dalcin ierr = MatSetType(B,mattype);CHKERRQ(ierr); 2650e885f1abSBarry Smith ierr = MatSetSizes(B,m,n,M,N);CHKERRQ(ierr); 26510e276705SLisandro Dalcin ierr = MatSetBlockSizesFromMats(B,A,A);CHKERRQ(ierr); 2652e885f1abSBarry Smith ierr = MatSetUp(B);CHKERRQ(ierr); 2653e885f1abSBarry Smith ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 2654e885f1abSBarry Smith 2655e885f1abSBarry Smith ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr); 2656e885f1abSBarry Smith ierr = SNESComputeJacobianDefault(snes,x,B,B,functx);CHKERRQ(ierr); 265712837594SBarry Smith 265812837594SBarry Smith ierr = MatDuplicate(B,MAT_COPY_VALUES,&D);CHKERRQ(ierr); 265912837594SBarry Smith ierr = MatAYPX(D,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 266012837594SBarry Smith ierr = MatNorm(D,NORM_FROBENIUS,&nrm);CHKERRQ(ierr); 2661e885f1abSBarry Smith ierr = MatNorm(A,NORM_FROBENIUS,&gnorm);CHKERRQ(ierr); 266212837594SBarry Smith ierr = MatDestroy(&D);CHKERRQ(ierr); 266312837594SBarry Smith if (!gnorm) gnorm = 1; /* just in case */ 266412837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n",(double)(nrm/gnorm),(double)nrm);CHKERRQ(ierr); 266512837594SBarry Smith 2666e885f1abSBarry Smith if (complete_print) { 266712837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Hand-coded Jacobian ----------\n");CHKERRQ(ierr); 26681878987eSStefano Zampini ierr = MatView(A,mviewer);CHKERRQ(ierr); 266912837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Finite difference Jacobian ----------\n");CHKERRQ(ierr); 26703325ff46SBarry Smith ierr = MatView(B,mviewer);CHKERRQ(ierr); 2671e885f1abSBarry Smith } 2672e885f1abSBarry Smith 2673df10fb39SFande Kong if (threshold_print || complete_print) { 2674e885f1abSBarry Smith PetscInt Istart, Iend, *ccols, bncols, cncols, j, row; 2675e885f1abSBarry Smith PetscScalar *cvals; 2676e885f1abSBarry Smith const PetscInt *bcols; 2677e885f1abSBarry Smith const PetscScalar *bvals; 2678e885f1abSBarry Smith 2679e885f1abSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 26800e276705SLisandro Dalcin ierr = MatSetType(C,mattype);CHKERRQ(ierr); 2681e885f1abSBarry Smith ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr); 26820e276705SLisandro Dalcin ierr = MatSetBlockSizesFromMats(C,A,A);CHKERRQ(ierr); 2683e885f1abSBarry Smith ierr = MatSetUp(C);CHKERRQ(ierr); 2684e885f1abSBarry Smith ierr = MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 26850e276705SLisandro Dalcin 26860e276705SLisandro Dalcin ierr = MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 2687e885f1abSBarry Smith ierr = MatGetOwnershipRange(B,&Istart,&Iend);CHKERRQ(ierr); 2688e885f1abSBarry Smith 2689e885f1abSBarry Smith for (row = Istart; row < Iend; row++) { 2690e885f1abSBarry Smith ierr = MatGetRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr); 2691e885f1abSBarry Smith ierr = PetscMalloc2(bncols,&ccols,bncols,&cvals);CHKERRQ(ierr); 2692e885f1abSBarry Smith for (j = 0, cncols = 0; j < bncols; j++) { 269323a52b1dSBarry Smith if (PetscAbsScalar(bvals[j]) > threshold) { 2694e885f1abSBarry Smith ccols[cncols] = bcols[j]; 2695e885f1abSBarry Smith cvals[cncols] = bvals[j]; 2696e885f1abSBarry Smith cncols += 1; 2697e885f1abSBarry Smith } 2698e885f1abSBarry Smith } 2699e885f1abSBarry Smith if (cncols) { 2700e885f1abSBarry Smith ierr = MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES);CHKERRQ(ierr); 2701e885f1abSBarry Smith } 2702e885f1abSBarry Smith ierr = MatRestoreRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr); 2703e885f1abSBarry Smith ierr = PetscFree2(ccols,cvals);CHKERRQ(ierr); 2704e885f1abSBarry Smith } 2705e885f1abSBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2706e885f1abSBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 270712837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n",(double)threshold);CHKERRQ(ierr); 270818d89885SKarl Rupp ierr = MatView(C,complete_print ? mviewer : viewer);CHKERRQ(ierr); 2709e885f1abSBarry Smith ierr = MatDestroy(&C);CHKERRQ(ierr); 2710e885f1abSBarry Smith } 271112837594SBarry Smith ierr = MatDestroy(&A);CHKERRQ(ierr); 2712e885f1abSBarry Smith ierr = MatDestroy(&B);CHKERRQ(ierr); 27132cd624f9SStefano Zampini ierr = MatDestroy(&JT);CHKERRQ(ierr); 27142cd624f9SStefano Zampini if (Jsave) jacobian = Jsave; 271512837594SBarry Smith if (jacobian != snes->jacobian_pre) { 271612837594SBarry Smith jacobian = snes->jacobian_pre; 271712837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," ---------- Testing Jacobian for preconditioner -------------\n");CHKERRQ(ierr); 271812837594SBarry Smith } 271912837594SBarry Smith else jacobian = NULL; 272012837594SBarry Smith } 2721a82339d0SMatthew G. Knepley ierr = VecDestroy(&x);CHKERRQ(ierr); 27223325ff46SBarry Smith if (complete_print) { 27233325ff46SBarry Smith ierr = PetscViewerPopFormat(mviewer);CHKERRQ(ierr); 27243325ff46SBarry Smith } 2725a0c90127SFande Kong if (mviewer) { ierr = PetscViewerDestroy(&mviewer);CHKERRQ(ierr); } 2726e885f1abSBarry Smith ierr = PetscViewerASCIISetTab(viewer,tabs);CHKERRQ(ierr); 2727e885f1abSBarry Smith PetscFunctionReturn(0); 2728e885f1abSBarry Smith } 2729e885f1abSBarry Smith 273062fef451SLois Curfman McInnes /*@ 2731bf388a1fSBarry Smith SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian(). 273262fef451SLois Curfman McInnes 2733d083f849SBarry Smith Collective on SNES 2734c7afd0dbSLois Curfman McInnes 273562fef451SLois Curfman McInnes Input Parameters: 2736c7afd0dbSLois Curfman McInnes + snes - the SNES context 2737c7afd0dbSLois Curfman McInnes - x - input vector 273862fef451SLois Curfman McInnes 273962fef451SLois Curfman McInnes Output Parameters: 2740c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 2741d1e9a80fSBarry Smith - B - optional preconditioning matrix 2742fee21e36SBarry Smith 2743e35cf81dSBarry Smith Options Database Keys: 2744e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 2745693365a8SJed Brown . -snes_lag_jacobian <lag> 2746455a5933SJed 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. 2747455a5933SJed 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 2748693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 2749693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 2750693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 27514c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 275294d6a431SBarry Smith . -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference 2753c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 2754c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 2755c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2756c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 27574c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 2758c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 2759c01495d3SJed Brown 2760e35cf81dSBarry Smith 276162fef451SLois Curfman McInnes Notes: 276262fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 276362fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 276462fef451SLois Curfman McInnes 276595452b02SPatrick Sanan Developer Notes: 276695452b02SPatrick 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 2767e885f1abSBarry Smith for with the SNESType of test that has been removed. 2768e885f1abSBarry Smith 276936851e7fSLois Curfman McInnes Level: developer 277036851e7fSLois Curfman McInnes 2771e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 277262fef451SLois Curfman McInnes @*/ 2773d1e9a80fSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat A,Mat B) 27749b94acceSBarry Smith { 2775dfbe8321SBarry Smith PetscErrorCode ierr; 2776ace3abfcSBarry Smith PetscBool flag; 27776cab3a1bSJed Brown DM dm; 2778942e3340SBarry Smith DMSNES sdm; 2779e0e3a89bSBarry Smith KSP ksp; 27803a40ed3dSBarry Smith 27813a40ed3dSBarry Smith PetscFunctionBegin; 27820700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 27830700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2784c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 278562796dfbSBarry Smith ierr = VecValidValues(X,2,PETSC_TRUE);CHKERRQ(ierr); 27866cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2787942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 27883232da50SPeter Brune 2789ce94432eSBarry Smith if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 2790ebd3b9afSBarry Smith 2791ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 2792ebd3b9afSBarry Smith 2793fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 2794fe3ffe1eSBarry Smith snes->lagjacobian = -1; 2795f5af7f23SKarl Rupp 2796fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 2797fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 2798e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 279994ab13aaSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr); 2800ebd3b9afSBarry Smith if (flag) { 280194ab13aaSBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 280294ab13aaSBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2803ebd3b9afSBarry Smith } 2804e35cf81dSBarry Smith PetscFunctionReturn(0); 280537ec4e1aSPeter Brune } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) { 2806e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 280794ab13aaSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr); 2808ebd3b9afSBarry Smith if (flag) { 280994ab13aaSBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 281094ab13aaSBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2811ebd3b9afSBarry Smith } 2812e35cf81dSBarry Smith PetscFunctionReturn(0); 2813e35cf81dSBarry Smith } 2814efd4aadfSBarry Smith if (snes->npc && snes->npcside== PC_LEFT) { 281594ab13aaSBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 281694ab13aaSBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2817d728fb7dSPeter Brune PetscFunctionReturn(0); 2818d728fb7dSPeter Brune } 2819e35cf81dSBarry Smith 282094ab13aaSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr); 28218860a134SJunchao Zhang ierr = VecLockReadPush(X);CHKERRQ(ierr); 2822d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 2823d1e9a80fSBarry Smith ierr = (*sdm->ops->computejacobian)(snes,X,A,B,sdm->jacobianctx);CHKERRQ(ierr); 2824d64ed03dSBarry Smith PetscStackPop; 28258860a134SJunchao Zhang ierr = VecLockReadPop(X);CHKERRQ(ierr); 282694ab13aaSBarry Smith ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr); 282728d58a37SPierre Jolivet 282828d58a37SPierre Jolivet /* attach latest linearization point to the preconditioning matrix */ 282928d58a37SPierre Jolivet ierr = PetscObjectCompose((PetscObject)B,"__SNES_latest_X",(PetscObject)X);CHKERRQ(ierr); 2830a8054027SBarry Smith 2831e0e3a89bSBarry Smith /* the next line ensures that snes->ksp exists */ 2832e0e3a89bSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 28333b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 28343b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 2835d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr); 28363b4f5425SBarry Smith snes->lagpreconditioner = -1; 28373b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 2838a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 2839d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr); 284037ec4e1aSPeter Brune } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) { 2841a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 2842d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr); 2843d1e9a80fSBarry Smith } else { 2844d1e9a80fSBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner\n");CHKERRQ(ierr); 2845d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr); 2846a8054027SBarry Smith } 2847a8054027SBarry Smith 2848e885f1abSBarry Smith ierr = SNESTestJacobian(snes);CHKERRQ(ierr); 28496d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 285094ab13aaSBarry Smith /* PetscValidHeaderSpecific(A,MAT_CLASSID,3); 285194ab13aaSBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,4); */ 2852693365a8SJed Brown { 2853693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 285416413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit",NULL,NULL,&flag);CHKERRQ(ierr); 285516413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr); 285616413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr); 285716413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_operator",NULL,NULL,&flag_operator);CHKERRQ(ierr); 2858693365a8SJed Brown if (flag || flag_draw || flag_contour) { 28590298fd71SBarry Smith Mat Bexp_mine = NULL,Bexp,FDexp; 2860693365a8SJed Brown PetscViewer vdraw,vstdout; 28616b3a5b13SJed Brown PetscBool flg; 2862693365a8SJed Brown if (flag_operator) { 28630bacdadaSStefano Zampini ierr = MatComputeOperator(A,MATAIJ,&Bexp_mine);CHKERRQ(ierr); 2864693365a8SJed Brown Bexp = Bexp_mine; 2865693365a8SJed Brown } else { 2866693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 2867b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompareAny((PetscObject)B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 286894ab13aaSBarry Smith if (flg) Bexp = B; 2869693365a8SJed Brown else { 2870693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 28710bacdadaSStefano Zampini ierr = MatComputeOperator(B,MATAIJ,&Bexp_mine);CHKERRQ(ierr); 2872693365a8SJed Brown Bexp = Bexp_mine; 2873693365a8SJed Brown } 2874693365a8SJed Brown } 2875693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 2876d1e9a80fSBarry Smith ierr = SNESComputeJacobianDefault(snes,X,FDexp,FDexp,NULL);CHKERRQ(ierr); 2877ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr); 2878693365a8SJed Brown if (flag_draw || flag_contour) { 28799e5d0892SLisandro Dalcin ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2880693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 28810298fd71SBarry Smith } else vdraw = NULL; 2882693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian");CHKERRQ(ierr); 2883693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 2884693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 2885693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 2886693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2887693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 2888693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2889693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 2890693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2891693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 2892693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2893693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 2894693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2895693365a8SJed Brown } 2896693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2897693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2898693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 2899693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 2900693365a8SJed Brown } 2901693365a8SJed Brown } 29024c30e9fbSJed Brown { 29036719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 29046719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 290516413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring",NULL,NULL,&flag);CHKERRQ(ierr); 290616413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_display",NULL,NULL,&flag_display);CHKERRQ(ierr); 290716413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr); 290816413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr); 290916413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",NULL,NULL,&flag_threshold);CHKERRQ(ierr); 291027b0f280SBarry Smith if (flag_threshold) { 2911c5929fdfSBarry Smith ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL);CHKERRQ(ierr); 2912c5929fdfSBarry Smith ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL);CHKERRQ(ierr); 291327b0f280SBarry Smith } 29146719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 29154c30e9fbSJed Brown Mat Bfd; 29164c30e9fbSJed Brown PetscViewer vdraw,vstdout; 2917335efc43SPeter Brune MatColoring coloring; 29184c30e9fbSJed Brown ISColoring iscoloring; 29194c30e9fbSJed Brown MatFDColoring matfdcoloring; 29204c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 29214c30e9fbSJed Brown void *funcctx; 29226719d8e4SJed Brown PetscReal norm1,norm2,normmax; 29234c30e9fbSJed Brown 292494ab13aaSBarry Smith ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 2925335efc43SPeter Brune ierr = MatColoringCreate(Bfd,&coloring);CHKERRQ(ierr); 2926335efc43SPeter Brune ierr = MatColoringSetType(coloring,MATCOLORINGSL);CHKERRQ(ierr); 2927335efc43SPeter Brune ierr = MatColoringSetFromOptions(coloring);CHKERRQ(ierr); 2928335efc43SPeter Brune ierr = MatColoringApply(coloring,&iscoloring);CHKERRQ(ierr); 2929335efc43SPeter Brune ierr = MatColoringDestroy(&coloring);CHKERRQ(ierr); 29304c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 2931f86b9fbaSHong Zhang ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 2932f86b9fbaSHong Zhang ierr = MatFDColoringSetUp(Bfd,iscoloring,matfdcoloring);CHKERRQ(ierr); 29334c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 29344c30e9fbSJed Brown 29354c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 29360298fd71SBarry Smith ierr = SNESGetFunction(snes,NULL,&func,&funcctx);CHKERRQ(ierr); 29374c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr); 29384c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 29394c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 29404c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 2941d1e9a80fSBarry Smith ierr = MatFDColoringApply(Bfd,matfdcoloring,X,snes);CHKERRQ(ierr); 29424c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 29434c30e9fbSJed Brown 2944ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr); 29454c30e9fbSJed Brown if (flag_draw || flag_contour) { 29469e5d0892SLisandro Dalcin ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 29474c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 29480298fd71SBarry Smith } else vdraw = NULL; 29494c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 295094ab13aaSBarry Smith if (flag_display) {ierr = MatView(B,vstdout);CHKERRQ(ierr);} 295194ab13aaSBarry Smith if (vdraw) {ierr = MatView(B,vdraw);CHKERRQ(ierr);} 29524c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 29536719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 29544c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 295594ab13aaSBarry Smith ierr = MatAYPX(Bfd,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 29564c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 29576719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 29584c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 295957622a8eSBarry 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); 29606719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 29614c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 29624c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 29634c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 29644c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 29654c30e9fbSJed Brown } 29664c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 29676719d8e4SJed Brown 29686719d8e4SJed Brown if (flag_threshold) { 29696719d8e4SJed Brown PetscInt bs,rstart,rend,i; 297094ab13aaSBarry Smith ierr = MatGetBlockSize(B,&bs);CHKERRQ(ierr); 297194ab13aaSBarry Smith ierr = MatGetOwnershipRange(B,&rstart,&rend);CHKERRQ(ierr); 29726719d8e4SJed Brown for (i=rstart; i<rend; i++) { 29736719d8e4SJed Brown const PetscScalar *ba,*ca; 29746719d8e4SJed Brown const PetscInt *bj,*cj; 29756719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 29766719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 297794ab13aaSBarry Smith ierr = MatGetRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr); 29786719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 297994ab13aaSBarry Smith if (bn != cn) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 29806719d8e4SJed Brown for (j=0; j<bn; j++) { 29816719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 29826719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 29836719d8e4SJed Brown maxentrycol = bj[j]; 29846719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 29856719d8e4SJed Brown } 29866719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 29876719d8e4SJed Brown maxdiffcol = bj[j]; 29886719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 29896719d8e4SJed Brown } 29906719d8e4SJed Brown if (rdiff > maxrdiff) { 29916719d8e4SJed Brown maxrdiffcol = bj[j]; 29926719d8e4SJed Brown maxrdiff = rdiff; 29936719d8e4SJed Brown } 29946719d8e4SJed Brown } 29956719d8e4SJed Brown if (maxrdiff > 1) { 299657622a8eSBarry 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); 29976719d8e4SJed Brown for (j=0; j<bn; j++) { 29986719d8e4SJed Brown PetscReal rdiff; 29996719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 30006719d8e4SJed Brown if (rdiff > 1) { 300157622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(vstdout," (%D,%g:%g)",bj[j],(double)PetscRealPart(ba[j]),(double)PetscRealPart(ca[j]));CHKERRQ(ierr); 30026719d8e4SJed Brown } 30036719d8e4SJed Brown } 30046719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 30056719d8e4SJed Brown } 300694ab13aaSBarry Smith ierr = MatRestoreRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr); 30076719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 30086719d8e4SJed Brown } 30096719d8e4SJed Brown } 30104c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 30114c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 30124c30e9fbSJed Brown } 30134c30e9fbSJed Brown } 30143a40ed3dSBarry Smith PetscFunctionReturn(0); 30159b94acceSBarry Smith } 30169b94acceSBarry Smith 3017bf388a1fSBarry Smith /*MC 3018411c0326SBarry Smith SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES 3019bf388a1fSBarry Smith 3020bf388a1fSBarry Smith Synopsis: 3021411c0326SBarry Smith #include "petscsnes.h" 3022411c0326SBarry Smith PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx); 3023bf388a1fSBarry Smith 30241843f636SBarry Smith Collective on snes 30251843f636SBarry Smith 30261843f636SBarry Smith Input Parameters: 30271843f636SBarry Smith + x - input vector, the Jacobian is to be computed at this value 3028bf388a1fSBarry Smith - ctx - [optional] user-defined Jacobian context 3029bf388a1fSBarry Smith 30301843f636SBarry Smith Output Parameters: 30311843f636SBarry Smith + Amat - the matrix that defines the (approximate) Jacobian 30321843f636SBarry Smith - Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 30331843f636SBarry Smith 3034878cb397SSatish Balay Level: intermediate 3035878cb397SSatish Balay 3036bf388a1fSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction(), SNESSetJacobian(), SNESGetJacobian() 3037bf388a1fSBarry Smith M*/ 3038bf388a1fSBarry Smith 30399b94acceSBarry Smith /*@C 30409b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 3041044dda88SLois Curfman McInnes location to store the matrix. 30429b94acceSBarry Smith 3043d083f849SBarry Smith Logically Collective on SNES 3044c7afd0dbSLois Curfman McInnes 30459b94acceSBarry Smith Input Parameters: 3046c7afd0dbSLois Curfman McInnes + snes - the SNES context 3047e5d3d808SBarry Smith . Amat - the matrix that defines the (approximate) Jacobian 3048e5d3d808SBarry Smith . Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 3049411c0326SBarry Smith . J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details 3050c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 30510298fd71SBarry Smith Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value) 30529b94acceSBarry Smith 30539b94acceSBarry Smith Notes: 3054e5d3d808SBarry Smith If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on 305516913363SBarry Smith each matrix. 305616913363SBarry Smith 3057895c21f2SBarry Smith If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null 3058895c21f2SBarry Smith space to Amat and the KSP solvers will automatically use that null space as needed during the solution process. 3059895c21f2SBarry Smith 30608d359177SBarry Smith If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument 3061a8a26c1eSJed Brown must be a MatFDColoring. 3062a8a26c1eSJed Brown 3063c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 3064c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 3065c3cc8fd1SJed Brown 306636851e7fSLois Curfman McInnes Level: beginner 306736851e7fSLois Curfman McInnes 3068411c0326SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESComputeJacobianDefaultColor(), MatStructure, J, 3069411c0326SBarry Smith SNESSetPicard(), SNESJacobianFunction 30709b94acceSBarry Smith @*/ 3071d1e9a80fSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx) 30729b94acceSBarry Smith { 3073dfbe8321SBarry Smith PetscErrorCode ierr; 30746cab3a1bSJed Brown DM dm; 30753a7fca6bSBarry Smith 30763a40ed3dSBarry Smith PetscFunctionBegin; 30770700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3078e5d3d808SBarry Smith if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 3079e5d3d808SBarry Smith if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 3080e5d3d808SBarry Smith if (Amat) PetscCheckSameComm(snes,1,Amat,2); 3081e5d3d808SBarry Smith if (Pmat) PetscCheckSameComm(snes,1,Pmat,3); 30826cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3083f8b49ee9SBarry Smith ierr = DMSNESSetJacobian(dm,J,ctx);CHKERRQ(ierr); 3084e5d3d808SBarry Smith if (Amat) { 3085e5d3d808SBarry Smith ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 30866bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 3087f5af7f23SKarl Rupp 3088e5d3d808SBarry Smith snes->jacobian = Amat; 30893a7fca6bSBarry Smith } 3090e5d3d808SBarry Smith if (Pmat) { 3091e5d3d808SBarry Smith ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr); 30926bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 3093f5af7f23SKarl Rupp 3094e5d3d808SBarry Smith snes->jacobian_pre = Pmat; 30953a7fca6bSBarry Smith } 30963a40ed3dSBarry Smith PetscFunctionReturn(0); 30979b94acceSBarry Smith } 309862fef451SLois Curfman McInnes 3099c2aafc4cSSatish Balay /*@C 3100b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 3101b4fd4287SBarry Smith provided context for evaluating the Jacobian. 3102b4fd4287SBarry Smith 3103c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 3104c7afd0dbSLois Curfman McInnes 3105b4fd4287SBarry Smith Input Parameter: 3106b4fd4287SBarry Smith . snes - the nonlinear solver context 3107b4fd4287SBarry Smith 3108b4fd4287SBarry Smith Output Parameters: 3109e5d3d808SBarry Smith + Amat - location to stash (approximate) Jacobian matrix (or NULL) 3110e5d3d808SBarry Smith . Pmat - location to stash matrix used to compute the preconditioner (or NULL) 3111411c0326SBarry Smith . J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence 31120298fd71SBarry Smith - ctx - location to stash Jacobian ctx (or NULL) 3113fee21e36SBarry Smith 311436851e7fSLois Curfman McInnes Level: advanced 311536851e7fSLois Curfman McInnes 3116411c0326SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian(), SNESJacobianFunction, SNESGetFunction() 3117b4fd4287SBarry Smith @*/ 3118d1e9a80fSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx) 3119b4fd4287SBarry Smith { 31206cab3a1bSJed Brown PetscErrorCode ierr; 31216cab3a1bSJed Brown DM dm; 3122942e3340SBarry Smith DMSNES sdm; 31236cab3a1bSJed Brown 31243a40ed3dSBarry Smith PetscFunctionBegin; 31250700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3126e5d3d808SBarry Smith if (Amat) *Amat = snes->jacobian; 3127e5d3d808SBarry Smith if (Pmat) *Pmat = snes->jacobian_pre; 31286cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3129942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 3130f8b49ee9SBarry Smith if (J) *J = sdm->ops->computejacobian; 31316cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 31323a40ed3dSBarry Smith PetscFunctionReturn(0); 3133b4fd4287SBarry Smith } 3134b4fd4287SBarry Smith 313558b371f3SBarry Smith static PetscErrorCode SNESSetDefaultComputeJacobian(SNES snes) 313658b371f3SBarry Smith { 313758b371f3SBarry Smith PetscErrorCode ierr; 313858b371f3SBarry Smith DM dm; 313958b371f3SBarry Smith DMSNES sdm; 314058b371f3SBarry Smith 314158b371f3SBarry Smith PetscFunctionBegin; 314258b371f3SBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 314358b371f3SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 314458b371f3SBarry Smith if (!sdm->ops->computejacobian && snes->jacobian_pre) { 314558b371f3SBarry Smith DM dm; 314658b371f3SBarry Smith PetscBool isdense,ismf; 314758b371f3SBarry Smith 314858b371f3SBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 314958b371f3SBarry Smith ierr = PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre,&isdense,MATSEQDENSE,MATMPIDENSE,MATDENSE,NULL);CHKERRQ(ierr); 315058b371f3SBarry Smith ierr = PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre,&ismf,MATMFFD,MATSHELL,NULL);CHKERRQ(ierr); 315158b371f3SBarry Smith if (isdense) { 315258b371f3SBarry Smith ierr = DMSNESSetJacobian(dm,SNESComputeJacobianDefault,NULL);CHKERRQ(ierr); 315358b371f3SBarry Smith } else if (!ismf) { 315458b371f3SBarry Smith ierr = DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr); 315558b371f3SBarry Smith } 315658b371f3SBarry Smith } 315758b371f3SBarry Smith PetscFunctionReturn(0); 315858b371f3SBarry Smith } 315958b371f3SBarry Smith 31609b94acceSBarry Smith /*@ 31619b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 3162272ac6f2SLois Curfman McInnes of a nonlinear solver. 31639b94acceSBarry Smith 3164fee21e36SBarry Smith Collective on SNES 3165fee21e36SBarry Smith 3166c7afd0dbSLois Curfman McInnes Input Parameters: 316770e92668SMatthew Knepley . snes - the SNES context 3168c7afd0dbSLois Curfman McInnes 3169272ac6f2SLois Curfman McInnes Notes: 3170272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 3171272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 3172272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 3173272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 3174272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 3175272ac6f2SLois Curfman McInnes 317636851e7fSLois Curfman McInnes Level: advanced 317736851e7fSLois Curfman McInnes 31789b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 31799b94acceSBarry Smith @*/ 31807087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 31819b94acceSBarry Smith { 3182dfbe8321SBarry Smith PetscErrorCode ierr; 31836cab3a1bSJed Brown DM dm; 3184942e3340SBarry Smith DMSNES sdm; 3185c35f09e5SBarry Smith SNESLineSearch linesearch, pclinesearch; 31866e2a1849SPeter Brune void *lsprectx,*lspostctx; 31876b2b7091SBarry Smith PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*); 31886b2b7091SBarry Smith PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*); 31896e2a1849SPeter Brune PetscErrorCode (*func)(SNES,Vec,Vec,void*); 31906e2a1849SPeter Brune Vec f,fpc; 31916e2a1849SPeter Brune void *funcctx; 3192d1e9a80fSBarry Smith PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*); 31931eb13d49SPeter Brune void *jacctx,*appctx; 319432b97717SPeter Brune Mat j,jpre; 31953a40ed3dSBarry Smith 31963a40ed3dSBarry Smith PetscFunctionBegin; 31970700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31984dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 3199e3ed9ee7SBarry Smith ierr = PetscLogEventBegin(SNES_Setup,snes,0,0,0);CHKERRQ(ierr); 32009b94acceSBarry Smith 32017adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 320204d7464bSBarry Smith ierr = SNESSetType(snes,SNESNEWTONLS);CHKERRQ(ierr); 320385385478SLisandro Dalcin } 320485385478SLisandro Dalcin 32050298fd71SBarry Smith ierr = SNESGetFunction(snes,&snes->vec_func,NULL,NULL);CHKERRQ(ierr); 320658c9b817SLisandro Dalcin 32076cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3208942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 3209ce94432eSBarry Smith if (!sdm->ops->computefunction) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object"); 321058b371f3SBarry Smith ierr = SNESSetDefaultComputeJacobian(snes);CHKERRQ(ierr); 321158b371f3SBarry Smith 32126cab3a1bSJed Brown if (!snes->vec_func) { 32136cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 3214214df951SJed Brown } 3215efd51863SBarry Smith 321622d28d08SBarry Smith if (!snes->ksp) { 321722d28d08SBarry Smith ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr); 321822d28d08SBarry Smith } 3219b710008aSBarry Smith 3220d8d34be6SBarry Smith if (snes->linesearch) { 32217601faf0SJed Brown ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 3222ed07d7d7SPeter Brune ierr = SNESLineSearchSetFunction(snes->linesearch,SNESComputeFunction);CHKERRQ(ierr); 3223d8d34be6SBarry Smith } 32249e764e56SPeter Brune 3225efd4aadfSBarry Smith if (snes->npc && (snes->npcside== PC_LEFT)) { 3226172a4300SPeter Brune snes->mf = PETSC_TRUE; 3227172a4300SPeter Brune snes->mf_operator = PETSC_FALSE; 3228172a4300SPeter Brune } 3229d8f46077SPeter Brune 3230efd4aadfSBarry Smith if (snes->npc) { 32316e2a1849SPeter Brune /* copy the DM over */ 32326e2a1849SPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3233efd4aadfSBarry Smith ierr = SNESSetDM(snes->npc,dm);CHKERRQ(ierr); 32346e2a1849SPeter Brune 32356e2a1849SPeter Brune ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr); 32366e2a1849SPeter Brune ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr); 3237efd4aadfSBarry Smith ierr = SNESSetFunction(snes->npc,fpc,func,funcctx);CHKERRQ(ierr); 323832b97717SPeter Brune ierr = SNESGetJacobian(snes,&j,&jpre,&jac,&jacctx);CHKERRQ(ierr); 3239efd4aadfSBarry Smith ierr = SNESSetJacobian(snes->npc,j,jpre,jac,jacctx);CHKERRQ(ierr); 32401eb13d49SPeter Brune ierr = SNESGetApplicationContext(snes,&appctx);CHKERRQ(ierr); 3241efd4aadfSBarry Smith ierr = SNESSetApplicationContext(snes->npc,appctx);CHKERRQ(ierr); 32426e2a1849SPeter Brune ierr = VecDestroy(&fpc);CHKERRQ(ierr); 32436e2a1849SPeter Brune 32446e2a1849SPeter Brune /* copy the function pointers over */ 3245efd4aadfSBarry Smith ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr); 32466e2a1849SPeter Brune 32476e2a1849SPeter Brune /* default to 1 iteration */ 3248efd4aadfSBarry Smith ierr = SNESSetTolerances(snes->npc,0.0,0.0,0.0,1,snes->npc->max_funcs);CHKERRQ(ierr); 3249efd4aadfSBarry Smith if (snes->npcside==PC_RIGHT) { 3250efd4aadfSBarry Smith ierr = SNESSetNormSchedule(snes->npc,SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); 3251a9936a0cSPeter Brune } else { 3252efd4aadfSBarry Smith ierr = SNESSetNormSchedule(snes->npc,SNES_NORM_NONE);CHKERRQ(ierr); 3253a9936a0cSPeter Brune } 3254efd4aadfSBarry Smith ierr = SNESSetFromOptions(snes->npc);CHKERRQ(ierr); 32556e2a1849SPeter Brune 32566e2a1849SPeter Brune /* copy the line search context over */ 3257d8d34be6SBarry Smith if (snes->linesearch && snes->npc->linesearch) { 32587601faf0SJed Brown ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); 3259efd4aadfSBarry Smith ierr = SNESGetLineSearch(snes->npc,&pclinesearch);CHKERRQ(ierr); 32606b2b7091SBarry Smith ierr = SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx);CHKERRQ(ierr); 32616b2b7091SBarry Smith ierr = SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx);CHKERRQ(ierr); 32626b2b7091SBarry Smith ierr = SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx);CHKERRQ(ierr); 32636b2b7091SBarry Smith ierr = SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx);CHKERRQ(ierr); 32646e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr); 32656e2a1849SPeter Brune } 3266d8d34be6SBarry Smith } 326732b97717SPeter Brune if (snes->mf) { 326832b97717SPeter Brune ierr = SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);CHKERRQ(ierr); 326932b97717SPeter Brune } 327032b97717SPeter Brune if (snes->ops->usercompute && !snes->user) { 327132b97717SPeter Brune ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 327232b97717SPeter Brune } 32736e2a1849SPeter Brune 327437ec4e1aSPeter Brune snes->jac_iter = 0; 327537ec4e1aSPeter Brune snes->pre_iter = 0; 327637ec4e1aSPeter Brune 3277410397dcSLisandro Dalcin if (snes->ops->setup) { 3278410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 3279410397dcSLisandro Dalcin } 328058c9b817SLisandro Dalcin 328158b371f3SBarry Smith ierr = SNESSetDefaultComputeJacobian(snes);CHKERRQ(ierr); 328258b371f3SBarry Smith 3283efd4aadfSBarry Smith if (snes->npc && (snes->npcside== PC_LEFT)) { 32846c67d002SPeter Brune if (snes->functype == SNES_FUNCTION_PRECONDITIONED) { 3285d8d34be6SBarry Smith if (snes->linesearch){ 328655d4788fSPeter Brune ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); 3287be95d8f1SBarry Smith ierr = SNESLineSearchSetFunction(linesearch,SNESComputeFunctionDefaultNPC);CHKERRQ(ierr); 32886c67d002SPeter Brune } 32896c67d002SPeter Brune } 3290d8d34be6SBarry Smith } 3291e3ed9ee7SBarry Smith ierr = PetscLogEventEnd(SNES_Setup,snes,0,0,0);CHKERRQ(ierr); 32927aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 32933a40ed3dSBarry Smith PetscFunctionReturn(0); 32949b94acceSBarry Smith } 32959b94acceSBarry Smith 329637596af1SLisandro Dalcin /*@ 329737596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 329837596af1SLisandro Dalcin 329937596af1SLisandro Dalcin Collective on SNES 330037596af1SLisandro Dalcin 330137596af1SLisandro Dalcin Input Parameter: 330237596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 330337596af1SLisandro Dalcin 3304d25893d9SBarry Smith Level: intermediate 3305d25893d9SBarry Smith 330695452b02SPatrick Sanan Notes: 330795452b02SPatrick Sanan Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 330837596af1SLisandro Dalcin 330937596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 331037596af1SLisandro Dalcin @*/ 331137596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 331237596af1SLisandro Dalcin { 331337596af1SLisandro Dalcin PetscErrorCode ierr; 331437596af1SLisandro Dalcin 331537596af1SLisandro Dalcin PetscFunctionBegin; 331637596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3317d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 3318d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 33190298fd71SBarry Smith snes->user = NULL; 3320d25893d9SBarry Smith } 3321efd4aadfSBarry Smith if (snes->npc) { 3322efd4aadfSBarry Smith ierr = SNESReset(snes->npc);CHKERRQ(ierr); 33238a23116dSBarry Smith } 33248a23116dSBarry Smith 332537596af1SLisandro Dalcin if (snes->ops->reset) { 332637596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 332737596af1SLisandro Dalcin } 33289e764e56SPeter Brune if (snes->ksp) { 33299e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 33309e764e56SPeter Brune } 33319e764e56SPeter Brune 33329e764e56SPeter Brune if (snes->linesearch) { 3333f1c6b773SPeter Brune ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 33349e764e56SPeter Brune } 33359e764e56SPeter Brune 33366bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 33376bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 33386bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 33396bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 33406bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 33416bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 3342*bbc1464cSBarry Smith ierr = MatDestroy(&snes->picard);CHKERRQ(ierr); 3343c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 3344c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 3345f5af7f23SKarl Rupp 334640fdac6aSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 334740fdac6aSLawrence Mitchell 334837596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 334937596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 335037596af1SLisandro Dalcin PetscFunctionReturn(0); 335137596af1SLisandro Dalcin } 335237596af1SLisandro Dalcin 335352baeb72SSatish Balay /*@ 3354c4421ceaSFande Kong SNESConvergedReasonViewCancel - Clears all the reasonview functions for a SNES object. 3355c4421ceaSFande Kong 3356c4421ceaSFande Kong Collective on SNES 3357c4421ceaSFande Kong 3358c4421ceaSFande Kong Input Parameter: 3359c4421ceaSFande Kong . snes - iterative context obtained from SNESCreate() 3360c4421ceaSFande Kong 3361c4421ceaSFande Kong Level: intermediate 3362c4421ceaSFande Kong 3363c4421ceaSFande Kong .seealso: SNESCreate(), SNESDestroy(), SNESReset() 3364c4421ceaSFande Kong @*/ 3365c4421ceaSFande Kong PetscErrorCode SNESConvergedReasonViewCancel(SNES snes) 3366c4421ceaSFande Kong { 3367c4421ceaSFande Kong PetscErrorCode ierr; 3368c4421ceaSFande Kong PetscInt i; 3369c4421ceaSFande Kong 3370c4421ceaSFande Kong PetscFunctionBegin; 3371c4421ceaSFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3372c4421ceaSFande Kong for (i=0; i<snes->numberreasonviews; i++) { 3373c4421ceaSFande Kong if (snes->reasonviewdestroy[i]) { 3374c4421ceaSFande Kong ierr = (*snes->reasonviewdestroy[i])(&snes->reasonviewcontext[i]);CHKERRQ(ierr); 3375c4421ceaSFande Kong } 3376c4421ceaSFande Kong } 3377c4421ceaSFande Kong snes->numberreasonviews = 0; 3378c4421ceaSFande Kong PetscFunctionReturn(0); 3379c4421ceaSFande Kong } 3380c4421ceaSFande Kong 33811fb7b255SJunchao Zhang /*@C 33829b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 33839b94acceSBarry Smith with SNESCreate(). 33849b94acceSBarry Smith 3385c7afd0dbSLois Curfman McInnes Collective on SNES 3386c7afd0dbSLois Curfman McInnes 33879b94acceSBarry Smith Input Parameter: 33889b94acceSBarry Smith . snes - the SNES context 33899b94acceSBarry Smith 339036851e7fSLois Curfman McInnes Level: beginner 339136851e7fSLois Curfman McInnes 339263a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 33939b94acceSBarry Smith @*/ 33946bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 33959b94acceSBarry Smith { 33966849ba73SBarry Smith PetscErrorCode ierr; 33973a40ed3dSBarry Smith 33983a40ed3dSBarry Smith PetscFunctionBegin; 33996bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 34006bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 34019e5d0892SLisandro Dalcin if (--((PetscObject)(*snes))->refct > 0) {*snes = NULL; PetscFunctionReturn(0);} 3402d4bb536fSBarry Smith 34036bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 3404efd4aadfSBarry Smith ierr = SNESDestroy(&(*snes)->npc);CHKERRQ(ierr); 34056b8b9a38SLisandro Dalcin 3406e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 3407e04113cfSBarry Smith ierr = PetscObjectSAWsViewOff((PetscObject)*snes);CHKERRQ(ierr); 34086bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 34096d4c513bSLisandro Dalcin 341033124788SMatthew G. Knepley if ((*snes)->dm) {ierr = DMCoarsenHookRemove((*snes)->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,*snes);CHKERRQ(ierr);} 34116bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 34126bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 3413f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 34146b8b9a38SLisandro Dalcin 34156bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 34166bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 34176bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 34186b8b9a38SLisandro Dalcin } 3419071fcb05SBarry Smith if ((*snes)->conv_hist_alloc) { 3420071fcb05SBarry Smith ierr = PetscFree2((*snes)->conv_hist,(*snes)->conv_hist_its);CHKERRQ(ierr); 342158c9b817SLisandro Dalcin } 34226bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 3423c4421ceaSFande Kong ierr = SNESConvergedReasonViewCancel((*snes));CHKERRQ(ierr); 3424a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 34253a40ed3dSBarry Smith PetscFunctionReturn(0); 34269b94acceSBarry Smith } 34279b94acceSBarry Smith 34289b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 34299b94acceSBarry Smith 3430a8054027SBarry Smith /*@ 3431a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 3432a8054027SBarry Smith 34333f9fe445SBarry Smith Logically Collective on SNES 3434a8054027SBarry Smith 3435a8054027SBarry Smith Input Parameters: 3436a8054027SBarry Smith + snes - the SNES context 3437d8e291bfSBarry Smith - lag - 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 34383b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3439a8054027SBarry Smith 3440a8054027SBarry Smith Options Database Keys: 34413d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 34423d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 34433d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 34443d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3445a8054027SBarry Smith 3446a8054027SBarry Smith Notes: 3447a8054027SBarry Smith The default is 1 34483d5a8a6aSBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or SNESSetLagPreconditionerPersists() was called 3449d8e291bfSBarry Smith 3450d8e291bfSBarry Smith SNESSetLagPreconditionerPersists() allows using the same uniform lagging (for example every second solve) across multiple solves. 3451a8054027SBarry Smith 3452a8054027SBarry Smith Level: intermediate 3453a8054027SBarry Smith 34543d5a8a6aSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetLagPreconditionerPersists(), 34553d5a8a6aSBarry Smith SNESSetLagJacobianPersists() 3456a8054027SBarry Smith 3457a8054027SBarry Smith @*/ 34587087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 3459a8054027SBarry Smith { 3460a8054027SBarry Smith PetscFunctionBegin; 34610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3462e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 3463e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 3464c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 3465a8054027SBarry Smith snes->lagpreconditioner = lag; 3466a8054027SBarry Smith PetscFunctionReturn(0); 3467a8054027SBarry Smith } 3468a8054027SBarry Smith 3469efd51863SBarry Smith /*@ 3470efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 3471efd51863SBarry Smith 3472efd51863SBarry Smith Logically Collective on SNES 3473efd51863SBarry Smith 3474efd51863SBarry Smith Input Parameters: 3475efd51863SBarry Smith + snes - the SNES context 3476efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 3477efd51863SBarry Smith 3478efd51863SBarry Smith Options Database Keys: 3479efd51863SBarry Smith . -snes_grid_sequence <steps> 3480efd51863SBarry Smith 3481efd51863SBarry Smith Level: intermediate 3482efd51863SBarry Smith 3483c0df2a02SJed Brown Notes: 3484c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 3485c0df2a02SJed Brown 3486fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetGridSequence() 3487efd51863SBarry Smith 3488efd51863SBarry Smith @*/ 3489efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 3490efd51863SBarry Smith { 3491efd51863SBarry Smith PetscFunctionBegin; 3492efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3493efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 3494efd51863SBarry Smith snes->gridsequence = steps; 3495efd51863SBarry Smith PetscFunctionReturn(0); 3496efd51863SBarry Smith } 3497efd51863SBarry Smith 3498fa19ca70SBarry Smith /*@ 3499fa19ca70SBarry Smith SNESGetGridSequence - gets the number of steps of grid sequencing that SNES does 3500fa19ca70SBarry Smith 3501fa19ca70SBarry Smith Logically Collective on SNES 3502fa19ca70SBarry Smith 3503fa19ca70SBarry Smith Input Parameter: 3504fa19ca70SBarry Smith . snes - the SNES context 3505fa19ca70SBarry Smith 3506fa19ca70SBarry Smith Output Parameter: 3507fa19ca70SBarry Smith . steps - the number of refinements to do, defaults to 0 3508fa19ca70SBarry Smith 3509fa19ca70SBarry Smith Options Database Keys: 3510fa19ca70SBarry Smith . -snes_grid_sequence <steps> 3511fa19ca70SBarry Smith 3512fa19ca70SBarry Smith Level: intermediate 3513fa19ca70SBarry Smith 3514fa19ca70SBarry Smith Notes: 3515fa19ca70SBarry Smith Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 3516fa19ca70SBarry Smith 3517fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetGridSequence() 3518fa19ca70SBarry Smith 3519fa19ca70SBarry Smith @*/ 3520fa19ca70SBarry Smith PetscErrorCode SNESGetGridSequence(SNES snes,PetscInt *steps) 3521fa19ca70SBarry Smith { 3522fa19ca70SBarry Smith PetscFunctionBegin; 3523fa19ca70SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3524fa19ca70SBarry Smith *steps = snes->gridsequence; 3525fa19ca70SBarry Smith PetscFunctionReturn(0); 3526fa19ca70SBarry Smith } 3527fa19ca70SBarry Smith 3528a8054027SBarry Smith /*@ 3529a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 3530a8054027SBarry Smith 35313f9fe445SBarry Smith Not Collective 3532a8054027SBarry Smith 3533a8054027SBarry Smith Input Parameter: 3534a8054027SBarry Smith . snes - the SNES context 3535a8054027SBarry Smith 3536a8054027SBarry Smith Output Parameter: 3537a8054027SBarry 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 35383b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3539a8054027SBarry Smith 3540a8054027SBarry Smith Options Database Keys: 35413d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 35423d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 35433d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 35443d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3545a8054027SBarry Smith 3546a8054027SBarry Smith Notes: 3547a8054027SBarry Smith The default is 1 3548a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3549a8054027SBarry Smith 3550a8054027SBarry Smith Level: intermediate 3551a8054027SBarry Smith 35523d5a8a6aSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner(), SNESSetLagJacobianPersists(), SNESSetLagPreconditionerPersists() 3553a8054027SBarry Smith 3554a8054027SBarry Smith @*/ 35557087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 3556a8054027SBarry Smith { 3557a8054027SBarry Smith PetscFunctionBegin; 35580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3559a8054027SBarry Smith *lag = snes->lagpreconditioner; 3560a8054027SBarry Smith PetscFunctionReturn(0); 3561a8054027SBarry Smith } 3562a8054027SBarry Smith 3563e35cf81dSBarry Smith /*@ 3564e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 3565e35cf81dSBarry Smith often the preconditioner is rebuilt. 3566e35cf81dSBarry Smith 35673f9fe445SBarry Smith Logically Collective on SNES 3568e35cf81dSBarry Smith 3569e35cf81dSBarry Smith Input Parameters: 3570e35cf81dSBarry Smith + snes - the SNES context 3571e35cf81dSBarry 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 3572fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 3573e35cf81dSBarry Smith 3574e35cf81dSBarry Smith Options Database Keys: 35753d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 35763d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 35773d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 35783d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag. 3579e35cf81dSBarry Smith 3580e35cf81dSBarry Smith Notes: 3581e35cf81dSBarry Smith The default is 1 3582e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3583fe3ffe1eSBarry 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 3584fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 3585e35cf81dSBarry Smith 3586e35cf81dSBarry Smith Level: intermediate 3587e35cf81dSBarry Smith 35883d5a8a6aSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobianPersists(), SNESSetLagPreconditionerPersists() 3589e35cf81dSBarry Smith 3590e35cf81dSBarry Smith @*/ 35917087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 3592e35cf81dSBarry Smith { 3593e35cf81dSBarry Smith PetscFunctionBegin; 35940700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3595e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 3596e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 3597c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 3598e35cf81dSBarry Smith snes->lagjacobian = lag; 3599e35cf81dSBarry Smith PetscFunctionReturn(0); 3600e35cf81dSBarry Smith } 3601e35cf81dSBarry Smith 3602e35cf81dSBarry Smith /*@ 3603e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 3604e35cf81dSBarry Smith 36053f9fe445SBarry Smith Not Collective 3606e35cf81dSBarry Smith 3607e35cf81dSBarry Smith Input Parameter: 3608e35cf81dSBarry Smith . snes - the SNES context 3609e35cf81dSBarry Smith 3610e35cf81dSBarry Smith Output Parameter: 3611e35cf81dSBarry 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 3612e35cf81dSBarry Smith the Jacobian is built etc. 3613e35cf81dSBarry Smith 3614e35cf81dSBarry Smith Notes: 3615e35cf81dSBarry Smith The default is 1 36163d5a8a6aSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or SNESSetLagJacobianPersists() was called. 3617e35cf81dSBarry Smith 3618e35cf81dSBarry Smith Level: intermediate 3619e35cf81dSBarry Smith 36203d5a8a6aSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner(), SNESSetLagJacobianPersists(), SNESSetLagPreconditionerPersists() 3621e35cf81dSBarry Smith 3622e35cf81dSBarry Smith @*/ 36237087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 3624e35cf81dSBarry Smith { 3625e35cf81dSBarry Smith PetscFunctionBegin; 36260700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3627e35cf81dSBarry Smith *lag = snes->lagjacobian; 3628e35cf81dSBarry Smith PetscFunctionReturn(0); 3629e35cf81dSBarry Smith } 3630e35cf81dSBarry Smith 363137ec4e1aSPeter Brune /*@ 363237ec4e1aSPeter Brune SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves 363337ec4e1aSPeter Brune 363437ec4e1aSPeter Brune Logically collective on SNES 363537ec4e1aSPeter Brune 363637ec4e1aSPeter Brune Input Parameter: 363737ec4e1aSPeter Brune + snes - the SNES context 36389d7e2deaSPeter Brune - flg - jacobian lagging persists if true 363937ec4e1aSPeter Brune 364037ec4e1aSPeter Brune Options Database Keys: 36413d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 36423d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 36433d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 36443d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 36453d5a8a6aSBarry Smith 364637ec4e1aSPeter Brune 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 367137ec4e1aSPeter Brune Input Parameter: 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); 43047a1ec6d4SBarry Smith if (a) PetscValidScalarPointer(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 4392fe97e370SBarry Smith Note: This is NOT what one uses to update the ghost points before a function evaluation, that should be done at the beginning of your FormFunction() 4393fe97e370SBarry Smith This is not used by most users. 439476b2cf59SMatthew Knepley 43958d359177SBarry Smith .seealso SNESSetJacobian(), SNESSolve() 439676b2cf59SMatthew Knepley @*/ 43977087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 439876b2cf59SMatthew Knepley { 439976b2cf59SMatthew Knepley PetscFunctionBegin; 44000700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 4401e7788613SBarry Smith snes->ops->update = func; 440276b2cf59SMatthew Knepley PetscFunctionReturn(0); 440376b2cf59SMatthew Knepley } 440476b2cf59SMatthew Knepley 44059b94acceSBarry Smith /* 44069b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 44079b94acceSBarry Smith positive parameter delta. 44089b94acceSBarry Smith 44099b94acceSBarry Smith Input Parameters: 4410c7afd0dbSLois Curfman McInnes + snes - the SNES context 44119b94acceSBarry Smith . y - approximate solution of linear system 44129b94acceSBarry Smith . fnorm - 2-norm of current function 4413c7afd0dbSLois Curfman McInnes - delta - trust region size 44149b94acceSBarry Smith 44159b94acceSBarry Smith Output Parameters: 4416c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 44179b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 44189b94acceSBarry Smith region, and exceeds zero otherwise. 4419c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 44209b94acceSBarry Smith 44219b94acceSBarry Smith Note: 442204d7464bSBarry Smith For non-trust region methods such as SNESNEWTONLS, the parameter delta 44239b94acceSBarry Smith is set to be the maximum allowable step size. 44249b94acceSBarry Smith 44259b94acceSBarry Smith */ 4426dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 44279b94acceSBarry Smith { 4428064f8208SBarry Smith PetscReal nrm; 4429ea709b57SSatish Balay PetscScalar cnorm; 4430dfbe8321SBarry Smith PetscErrorCode ierr; 44313a40ed3dSBarry Smith 44323a40ed3dSBarry Smith PetscFunctionBegin; 44330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 44340700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 4435c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 4436184914b5SBarry Smith 4437064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 4438064f8208SBarry Smith if (nrm > *delta) { 4439064f8208SBarry Smith nrm = *delta/nrm; 4440064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 4441064f8208SBarry Smith cnorm = nrm; 44422dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 44439b94acceSBarry Smith *ynorm = *delta; 44449b94acceSBarry Smith } else { 44459b94acceSBarry Smith *gpnorm = 0.0; 4446064f8208SBarry Smith *ynorm = nrm; 44479b94acceSBarry Smith } 44483a40ed3dSBarry Smith PetscFunctionReturn(0); 44499b94acceSBarry Smith } 44509b94acceSBarry Smith 445191f3e32bSBarry Smith /*@C 445219a666eeSBarry Smith SNESConvergedReasonView - Displays the reason a SNES solve converged or diverged to a viewer 44532a359c20SBarry Smith 44542a359c20SBarry Smith Collective on SNES 44552a359c20SBarry Smith 44562a359c20SBarry Smith Parameter: 44572a359c20SBarry Smith + snes - iterative context obtained from SNESCreate() 44582a359c20SBarry Smith - viewer - the viewer to display the reason 44592a359c20SBarry Smith 44602a359c20SBarry Smith 44612a359c20SBarry Smith Options Database Keys: 4462ee300463SSatish Balay + -snes_converged_reason - print reason for converged or diverged, also prints number of iterations 4463ee300463SSatish Balay - -snes_converged_reason ::failed - only print reason and number of iterations when diverged 4464eafd5ff0SAlex Lindsay 446519a666eeSBarry Smith Notes: 446619a666eeSBarry Smith To change the format of the output call PetscViewerPushFormat(viewer,format) before this call. Use PETSC_VIEWER_DEFAULT for the default, 446719a666eeSBarry Smith use PETSC_VIEWER_FAILED to only display a reason if it fails. 44682a359c20SBarry Smith 44692a359c20SBarry Smith Level: beginner 44702a359c20SBarry Smith 447119a666eeSBarry Smith .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault(), SNESGetConvergedReason(), SNESConvergedReasonViewFromOptions(), 447219a666eeSBarry Smith PetscViewerPushFormat(), PetscViewerPopFormat() 44732a359c20SBarry Smith 44742a359c20SBarry Smith @*/ 447519a666eeSBarry Smith PetscErrorCode SNESConvergedReasonView(SNES snes,PetscViewer viewer) 44762a359c20SBarry Smith { 447775cca76cSMatthew G. Knepley PetscViewerFormat format; 44782a359c20SBarry Smith PetscBool isAscii; 447975cca76cSMatthew G. Knepley PetscErrorCode ierr; 44802a359c20SBarry Smith 44812a359c20SBarry Smith PetscFunctionBegin; 448219a666eeSBarry Smith if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 44832a359c20SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);CHKERRQ(ierr); 44842a359c20SBarry Smith if (isAscii) { 448575cca76cSMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 44862a359c20SBarry Smith ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 448775cca76cSMatthew G. Knepley if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 448875cca76cSMatthew G. Knepley DM dm; 448975cca76cSMatthew G. Knepley Vec u; 449075cca76cSMatthew G. Knepley PetscDS prob; 449175cca76cSMatthew G. Knepley PetscInt Nf, f; 449295cbbfd3SMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 449395cbbfd3SMatthew G. Knepley void **exactCtx; 449475cca76cSMatthew G. Knepley PetscReal error; 449575cca76cSMatthew G. Knepley 449675cca76cSMatthew G. Knepley ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 449775cca76cSMatthew G. Knepley ierr = SNESGetSolution(snes, &u);CHKERRQ(ierr); 449875cca76cSMatthew G. Knepley ierr = DMGetDS(dm, &prob);CHKERRQ(ierr); 449975cca76cSMatthew G. Knepley ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 450095cbbfd3SMatthew G. Knepley ierr = PetscMalloc2(Nf, &exactSol, Nf, &exactCtx);CHKERRQ(ierr); 450195cbbfd3SMatthew G. Knepley for (f = 0; f < Nf; ++f) {ierr = PetscDSGetExactSolution(prob, f, &exactSol[f], &exactCtx[f]);CHKERRQ(ierr);} 450295cbbfd3SMatthew G. Knepley ierr = DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error);CHKERRQ(ierr); 450395cbbfd3SMatthew G. Knepley ierr = PetscFree2(exactSol, exactCtx);CHKERRQ(ierr); 450475cca76cSMatthew G. Knepley if (error < 1.0e-11) {ierr = PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n");CHKERRQ(ierr);} 450575cca76cSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", error);CHKERRQ(ierr);} 450675cca76cSMatthew G. Knepley } 4507eafd5ff0SAlex Lindsay if (snes->reason > 0 && format != PETSC_VIEWER_FAILED) { 45082a359c20SBarry Smith if (((PetscObject) snes)->prefix) { 45092a359c20SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve converged due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 45102a359c20SBarry Smith } else { 45112a359c20SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 45122a359c20SBarry Smith } 4513eafd5ff0SAlex Lindsay } else if (snes->reason <= 0) { 45142a359c20SBarry Smith if (((PetscObject) snes)->prefix) { 45152a359c20SBarry 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); 45162a359c20SBarry Smith } else { 45172a359c20SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 45182a359c20SBarry Smith } 45192a359c20SBarry Smith } 45202a359c20SBarry Smith ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 45212a359c20SBarry Smith } 45222a359c20SBarry Smith PetscFunctionReturn(0); 45232a359c20SBarry Smith } 45242a359c20SBarry Smith 4525c4421ceaSFande Kong /*@C 4526c4421ceaSFande Kong SNESConvergedReasonViewSet - Sets an ADDITIONAL function that is to be used at the 4527c4421ceaSFande Kong end of the nonlinear solver to display the conver reason of the nonlinear solver. 4528c4421ceaSFande Kong 4529c4421ceaSFande Kong Logically Collective on SNES 4530c4421ceaSFande Kong 4531c4421ceaSFande Kong Input Parameters: 4532c4421ceaSFande Kong + snes - the SNES context 4533c4421ceaSFande Kong . f - the snes converged reason view function 4534c4421ceaSFande Kong . vctx - [optional] user-defined context for private data for the 4535c4421ceaSFande Kong snes converged reason view routine (use NULL if no context is desired) 4536c4421ceaSFande Kong - reasonviewdestroy - [optional] routine that frees reasonview context 4537c4421ceaSFande Kong (may be NULL) 4538c4421ceaSFande Kong 4539c4421ceaSFande Kong Options Database Keys: 4540c4421ceaSFande Kong + -snes_converged_reason - sets a default SNESConvergedReasonView() 4541c4421ceaSFande Kong - -snes_converged_reason_view_cancel - cancels all converged reason viewers that have 4542c4421ceaSFande Kong been hardwired into a code by 4543c4421ceaSFande Kong calls to SNESConvergedReasonViewSet(), but 4544c4421ceaSFande Kong does not cancel those set via 4545c4421ceaSFande Kong the options database. 4546c4421ceaSFande Kong 4547c4421ceaSFande Kong Notes: 4548c4421ceaSFande Kong Several different converged reason view routines may be set by calling 4549c4421ceaSFande Kong SNESConvergedReasonViewSet() multiple times; all will be called in the 4550c4421ceaSFande Kong order in which they were set. 4551c4421ceaSFande Kong 4552c4421ceaSFande Kong Level: intermediate 4553c4421ceaSFande Kong 4554c4421ceaSFande Kong .seealso: SNESConvergedReasonView(), SNESConvergedReasonViewCancel() 4555c4421ceaSFande Kong @*/ 4556c4421ceaSFande Kong PetscErrorCode SNESConvergedReasonViewSet(SNES snes,PetscErrorCode (*f)(SNES,void*),void *vctx,PetscErrorCode (*reasonviewdestroy)(void**)) 4557c4421ceaSFande Kong { 4558c4421ceaSFande Kong PetscInt i; 4559c4421ceaSFande Kong PetscErrorCode ierr; 4560c4421ceaSFande Kong PetscBool identical; 4561c4421ceaSFande Kong 4562c4421ceaSFande Kong PetscFunctionBegin; 4563c4421ceaSFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4564c4421ceaSFande Kong for (i=0; i<snes->numberreasonviews;i++) { 4565c4421ceaSFande Kong ierr = PetscMonitorCompare((PetscErrorCode (*)(void))f,vctx,reasonviewdestroy,(PetscErrorCode (*)(void))snes->reasonview[i],snes->reasonviewcontext[i],snes->reasonviewdestroy[i],&identical);CHKERRQ(ierr); 4566c4421ceaSFande Kong if (identical) PetscFunctionReturn(0); 4567c4421ceaSFande Kong } 4568c4421ceaSFande Kong if (snes->numberreasonviews >= MAXSNESREASONVIEWS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many SNES reasonview set"); 4569c4421ceaSFande Kong snes->reasonview[snes->numberreasonviews] = f; 4570c4421ceaSFande Kong snes->reasonviewdestroy[snes->numberreasonviews] = reasonviewdestroy; 4571c4421ceaSFande Kong snes->reasonviewcontext[snes->numberreasonviews++] = (void*)vctx; 4572c4421ceaSFande Kong PetscFunctionReturn(0); 4573c4421ceaSFande Kong } 4574c4421ceaSFande Kong 457591f3e32bSBarry Smith /*@ 457619a666eeSBarry Smith SNESConvergedReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed. 4577c4421ceaSFande Kong All the user-provided convergedReasonView routines will be involved as well, if they exist. 45782a359c20SBarry Smith 45792a359c20SBarry Smith Collective on SNES 45802a359c20SBarry Smith 45812a359c20SBarry Smith Input Parameters: 45822a359c20SBarry Smith . snes - the SNES object 45832a359c20SBarry Smith 45842a359c20SBarry Smith Level: intermediate 45852a359c20SBarry Smith 458619a666eeSBarry Smith .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault(), SNESGetConvergedReason(), SNESConvergedReasonView() 458719a666eeSBarry Smith 45882a359c20SBarry Smith @*/ 458919a666eeSBarry Smith PetscErrorCode SNESConvergedReasonViewFromOptions(SNES snes) 45902a359c20SBarry Smith { 45912a359c20SBarry Smith PetscErrorCode ierr; 45922a359c20SBarry Smith PetscViewer viewer; 45932a359c20SBarry Smith PetscBool flg; 45942a359c20SBarry Smith static PetscBool incall = PETSC_FALSE; 45952a359c20SBarry Smith PetscViewerFormat format; 4596c4421ceaSFande Kong PetscInt i; 45972a359c20SBarry Smith 45982a359c20SBarry Smith PetscFunctionBegin; 45992a359c20SBarry Smith if (incall) PetscFunctionReturn(0); 46002a359c20SBarry Smith incall = PETSC_TRUE; 4601c4421ceaSFande Kong 4602c4421ceaSFande Kong /* All user-provided viewers are called first, if they exist. */ 4603c4421ceaSFande Kong for (i=0; i<snes->numberreasonviews; i++) { 4604c4421ceaSFande Kong ierr = (*snes->reasonview[i])(snes,snes->reasonviewcontext[i]);CHKERRQ(ierr); 4605c4421ceaSFande Kong } 4606c4421ceaSFande Kong 4607c4421ceaSFande Kong /* Call PETSc default routine if users ask for it */ 460816413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_converged_reason",&viewer,&format,&flg);CHKERRQ(ierr); 46092a359c20SBarry Smith if (flg) { 46102a359c20SBarry Smith ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 461119a666eeSBarry Smith ierr = SNESConvergedReasonView(snes,viewer);CHKERRQ(ierr); 46122a359c20SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 46132a359c20SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 46142a359c20SBarry Smith } 46152a359c20SBarry Smith incall = PETSC_FALSE; 46162a359c20SBarry Smith PetscFunctionReturn(0); 46172a359c20SBarry Smith } 46182a359c20SBarry Smith 4619487a658cSBarry Smith /*@ 4620f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 4621f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 46229b94acceSBarry Smith 4623c7afd0dbSLois Curfman McInnes Collective on SNES 4624c7afd0dbSLois Curfman McInnes 4625b2002411SLois Curfman McInnes Input Parameters: 4626c7afd0dbSLois Curfman McInnes + snes - the SNES context 46270298fd71SBarry Smith . b - the constant part of the equation F(x) = b, or NULL to use zero. 462885385478SLisandro Dalcin - x - the solution vector. 46299b94acceSBarry Smith 4630b2002411SLois Curfman McInnes Notes: 46318ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 46328ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 46338ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 46348ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 46358ddd3da0SLois Curfman McInnes 463636851e7fSLois Curfman McInnes Level: beginner 463736851e7fSLois Curfman McInnes 4638c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 46399b94acceSBarry Smith @*/ 46407087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 46419b94acceSBarry Smith { 4642dfbe8321SBarry Smith PetscErrorCode ierr; 4643ace3abfcSBarry Smith PetscBool flg; 4644efd51863SBarry Smith PetscInt grid; 46450298fd71SBarry Smith Vec xcreated = NULL; 4646caa4e7f2SJed Brown DM dm; 4647052efed2SBarry Smith 46483a40ed3dSBarry Smith PetscFunctionBegin; 46490700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4650a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 4651a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 46520700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 465385385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 465485385478SLisandro Dalcin 465534b4d3a8SMatthew G. Knepley /* High level operations using the nonlinear solver */ 465606fc46c8SMatthew G. Knepley { 465706fc46c8SMatthew G. Knepley PetscViewer viewer; 465806fc46c8SMatthew G. Knepley PetscViewerFormat format; 46597c88af5aSMatthew G. Knepley PetscInt num; 466006fc46c8SMatthew G. Knepley PetscBool flg; 466106fc46c8SMatthew G. Knepley static PetscBool incall = PETSC_FALSE; 466206fc46c8SMatthew G. Knepley 466306fc46c8SMatthew G. Knepley if (!incall) { 466434b4d3a8SMatthew G. Knepley /* Estimate the convergence rate of the discretization */ 466516413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) snes),((PetscObject)snes)->options, ((PetscObject) snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg);CHKERRQ(ierr); 466606fc46c8SMatthew G. Knepley if (flg) { 466706fc46c8SMatthew G. Knepley PetscConvEst conv; 466846079b62SMatthew G. Knepley DM dm; 466946079b62SMatthew G. Knepley PetscReal *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */ 467046079b62SMatthew G. Knepley PetscInt Nf; 467106fc46c8SMatthew G. Knepley 467206fc46c8SMatthew G. Knepley incall = PETSC_TRUE; 467346079b62SMatthew G. Knepley ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 467446079b62SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 4675ca5a3622SMatthew G. Knepley ierr = PetscCalloc1(Nf, &alpha);CHKERRQ(ierr); 467606fc46c8SMatthew G. Knepley ierr = PetscConvEstCreate(PetscObjectComm((PetscObject) snes), &conv);CHKERRQ(ierr); 4677900f6b5bSMatthew G. Knepley ierr = PetscConvEstSetSolver(conv, (PetscObject) snes);CHKERRQ(ierr); 467806fc46c8SMatthew G. Knepley ierr = PetscConvEstSetFromOptions(conv);CHKERRQ(ierr); 46790955ed61SMatthew G. Knepley ierr = PetscConvEstSetUp(conv);CHKERRQ(ierr); 468046079b62SMatthew G. Knepley ierr = PetscConvEstGetConvRate(conv, alpha);CHKERRQ(ierr); 468106fc46c8SMatthew G. Knepley ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr); 468206fc46c8SMatthew G. Knepley ierr = PetscConvEstRateView(conv, alpha, viewer);CHKERRQ(ierr); 468306fc46c8SMatthew G. Knepley ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 468406fc46c8SMatthew G. Knepley ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 468506fc46c8SMatthew G. Knepley ierr = PetscConvEstDestroy(&conv);CHKERRQ(ierr); 468646079b62SMatthew G. Knepley ierr = PetscFree(alpha);CHKERRQ(ierr); 468706fc46c8SMatthew G. Knepley incall = PETSC_FALSE; 468806fc46c8SMatthew G. Knepley } 468934b4d3a8SMatthew G. Knepley /* Adaptively refine the initial grid */ 4690b2588ea6SMatthew G. Knepley num = 1; 4691b2588ea6SMatthew G. Knepley ierr = PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_initial", &num, &flg);CHKERRQ(ierr); 469234b4d3a8SMatthew G. Knepley if (flg) { 469334b4d3a8SMatthew G. Knepley DMAdaptor adaptor; 469434b4d3a8SMatthew G. Knepley 469534b4d3a8SMatthew G. Knepley incall = PETSC_TRUE; 4696ea13f565SStefano Zampini ierr = DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor);CHKERRQ(ierr); 469734b4d3a8SMatthew G. Knepley ierr = DMAdaptorSetSolver(adaptor, snes);CHKERRQ(ierr); 4698b2588ea6SMatthew G. Knepley ierr = DMAdaptorSetSequenceLength(adaptor, num);CHKERRQ(ierr); 469934b4d3a8SMatthew G. Knepley ierr = DMAdaptorSetFromOptions(adaptor);CHKERRQ(ierr); 470034b4d3a8SMatthew G. Knepley ierr = DMAdaptorSetUp(adaptor);CHKERRQ(ierr); 470134b4d3a8SMatthew G. Knepley ierr = DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x);CHKERRQ(ierr); 470234b4d3a8SMatthew G. Knepley ierr = DMAdaptorDestroy(&adaptor);CHKERRQ(ierr); 470334b4d3a8SMatthew G. Knepley incall = PETSC_FALSE; 470434b4d3a8SMatthew G. Knepley } 47057c88af5aSMatthew G. Knepley /* Use grid sequencing to adapt */ 47067c88af5aSMatthew G. Knepley num = 0; 47077c88af5aSMatthew G. Knepley ierr = PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_sequence", &num, NULL);CHKERRQ(ierr); 47087c88af5aSMatthew G. Knepley if (num) { 47097c88af5aSMatthew G. Knepley DMAdaptor adaptor; 47107c88af5aSMatthew G. Knepley 47117c88af5aSMatthew G. Knepley incall = PETSC_TRUE; 4712ea13f565SStefano Zampini ierr = DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor);CHKERRQ(ierr); 47137c88af5aSMatthew G. Knepley ierr = DMAdaptorSetSolver(adaptor, snes);CHKERRQ(ierr); 47147c88af5aSMatthew G. Knepley ierr = DMAdaptorSetSequenceLength(adaptor, num);CHKERRQ(ierr); 47157c88af5aSMatthew G. Knepley ierr = DMAdaptorSetFromOptions(adaptor);CHKERRQ(ierr); 47167c88af5aSMatthew G. Knepley ierr = DMAdaptorSetUp(adaptor);CHKERRQ(ierr); 47177c88af5aSMatthew G. Knepley ierr = DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x);CHKERRQ(ierr); 47187c88af5aSMatthew G. Knepley ierr = DMAdaptorDestroy(&adaptor);CHKERRQ(ierr); 47197c88af5aSMatthew G. Knepley incall = PETSC_FALSE; 47207c88af5aSMatthew G. Knepley } 472106fc46c8SMatthew G. Knepley } 472206fc46c8SMatthew G. Knepley } 4723caa4e7f2SJed Brown if (!x) { 4724caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4725caa4e7f2SJed Brown ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 4726a69afd8bSBarry Smith x = xcreated; 4727a69afd8bSBarry Smith } 4728ce1779c8SBarry Smith ierr = SNESViewFromOptions(snes,NULL,"-snes_view_pre");CHKERRQ(ierr); 4729f05ece33SBarry Smith 4730ce94432eSBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);} 4731efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 4732efd51863SBarry Smith 473385385478SLisandro Dalcin /* set solution vector */ 4734efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 47356bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 473685385478SLisandro Dalcin snes->vec_sol = x; 4737caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4738caa4e7f2SJed Brown 4739caa4e7f2SJed Brown /* set affine vector if provided */ 474085385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 47416bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 474285385478SLisandro Dalcin snes->vec_rhs = b; 474385385478SLisandro Dalcin 4744bfdd6862SPatrick 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"); 4745154060b5SMatthew G. Knepley if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 4746154060b5SMatthew 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"); 4747154060b5SMatthew G. Knepley if (!snes->vec_sol_update /* && snes->vec_sol */) { 4748154060b5SMatthew G. Knepley ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 4749154060b5SMatthew G. Knepley ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update);CHKERRQ(ierr); 4750154060b5SMatthew G. Knepley } 4751154060b5SMatthew G. Knepley ierr = DMShellSetGlobalVector(dm,snes->vec_sol);CHKERRQ(ierr); 475270e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 47533f149594SLisandro Dalcin 47547eee914bSBarry Smith if (!grid) { 47557eee914bSBarry Smith if (snes->ops->computeinitialguess) { 4756d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 4757d25893d9SBarry Smith } 4758dd568438SSatish Balay } 4759d25893d9SBarry Smith 4760abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 4761971e163fSPeter Brune if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;} 4762d5e45103SBarry Smith 47633f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 47644936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 476585385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 476617186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 4767422a814eSBarry Smith snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */ 47683f149594SLisandro Dalcin 476937ec4e1aSPeter Brune if (snes->lagjac_persist) snes->jac_iter += snes->iter; 477037ec4e1aSPeter Brune if (snes->lagpre_persist) snes->pre_iter += snes->iter; 477137ec4e1aSPeter Brune 477216413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_test_local_min",NULL,NULL,&flg);CHKERRQ(ierr); 4773da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 4774c4421ceaSFande Kong /* Call converged reason views. This may involve user-provided viewers as well */ 477519a666eeSBarry Smith ierr = SNESConvergedReasonViewFromOptions(snes);CHKERRQ(ierr); 47765968eb51SBarry Smith 4777ce94432eSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 47789c8e83a9SBarry Smith if (snes->reason < 0) break; 4779efd51863SBarry Smith if (grid < snes->gridsequence) { 4780efd51863SBarry Smith DM fine; 4781efd51863SBarry Smith Vec xnew; 4782efd51863SBarry Smith Mat interp; 4783efd51863SBarry Smith 4784ce94432eSBarry Smith ierr = DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine);CHKERRQ(ierr); 4785ce94432eSBarry Smith if (!fine) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 47860298fd71SBarry Smith ierr = DMCreateInterpolation(snes->dm,fine,&interp,NULL);CHKERRQ(ierr); 4787efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 4788efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 4789c833c3b5SJed Brown ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr); 4790efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 4791efd51863SBarry Smith x = xnew; 4792efd51863SBarry Smith 4793efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 4794efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 4795352f405dSMatthew G. Knepley ierr = SNESResetFromOptions(snes);CHKERRQ(ierr); 4796efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 4797ce94432eSBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr); 4798efd51863SBarry Smith } 4799efd51863SBarry Smith } 4800ce1779c8SBarry Smith ierr = SNESViewFromOptions(snes,NULL,"-snes_view");CHKERRQ(ierr); 4801685405a1SBarry Smith ierr = VecViewFromOptions(snes->vec_sol,(PetscObject)snes,"-snes_view_solution");CHKERRQ(ierr); 4802c0f0dcc3SMatthew G. Knepley ierr = DMMonitor(snes->dm);CHKERRQ(ierr); 48033f7e2da0SPeter Brune 4804a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 4805e04113cfSBarry Smith ierr = PetscObjectSAWsBlock((PetscObject)snes);CHKERRQ(ierr); 48063a40ed3dSBarry Smith PetscFunctionReturn(0); 48079b94acceSBarry Smith } 48089b94acceSBarry Smith 48099b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 48109b94acceSBarry Smith 481182bf6240SBarry Smith /*@C 48124b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 48139b94acceSBarry Smith 4814fee21e36SBarry Smith Collective on SNES 4815fee21e36SBarry Smith 4816c7afd0dbSLois Curfman McInnes Input Parameters: 4817c7afd0dbSLois Curfman McInnes + snes - the SNES context 4818454a90a3SBarry Smith - type - a known method 4819c7afd0dbSLois Curfman McInnes 4820c7afd0dbSLois Curfman McInnes Options Database Key: 4821454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 482204d7464bSBarry Smith of available methods (for instance, newtonls or newtontr) 4823ae12b187SLois Curfman McInnes 48249b94acceSBarry Smith Notes: 4825e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 482604d7464bSBarry Smith + SNESNEWTONLS - Newton's method with line search 4827c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 4828a2b725a8SWilliam Gropp - SNESNEWTONTR - Newton's method with trust region 4829c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 48309b94acceSBarry Smith 4831ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 4832ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 4833ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 4834ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 4835ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 4836ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 4837ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 4838ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 4839ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 4840b0a32e0cSBarry Smith appropriate method. 484136851e7fSLois Curfman McInnes 484295452b02SPatrick Sanan Developer Notes: 484395452b02SPatrick Sanan SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates 48448f6c3df8SBarry Smith the constructor in that list and calls it to create the spexific object. 48458f6c3df8SBarry Smith 484636851e7fSLois Curfman McInnes Level: intermediate 4847a703fe33SLois Curfman McInnes 48488f6c3df8SBarry Smith .seealso: SNESType, SNESCreate(), SNESDestroy(), SNESGetType(), SNESSetFromOptions() 4849435da068SBarry Smith 48509b94acceSBarry Smith @*/ 485119fd82e9SBarry Smith PetscErrorCode SNESSetType(SNES snes,SNESType type) 48529b94acceSBarry Smith { 4853dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 4854ace3abfcSBarry Smith PetscBool match; 48553a40ed3dSBarry Smith 48563a40ed3dSBarry Smith PetscFunctionBegin; 48570700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 48584482741eSBarry Smith PetscValidCharPointer(type,2); 485982bf6240SBarry Smith 4860251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 48610f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 486292ff6ae8SBarry Smith 48631c9cd337SJed Brown ierr = PetscFunctionListFind(SNESList,type,&r);CHKERRQ(ierr); 4864e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 486575396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 4866b5c23020SJed Brown if (snes->ops->destroy) { 4867b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 48680298fd71SBarry Smith snes->ops->destroy = NULL; 4869b5c23020SJed Brown } 487075396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 48719e5d0892SLisandro Dalcin snes->ops->setup = NULL; 48729e5d0892SLisandro Dalcin snes->ops->solve = NULL; 48739e5d0892SLisandro Dalcin snes->ops->view = NULL; 48749e5d0892SLisandro Dalcin snes->ops->setfromoptions = NULL; 48759e5d0892SLisandro Dalcin snes->ops->destroy = NULL; 48767fe760d5SStefano Zampini 48777fe760d5SStefano Zampini /* It may happen the user has customized the line search before calling SNESSetType */ 48787fe760d5SStefano Zampini if (((PetscObject)snes)->type_name) { 4879d8d34be6SBarry Smith ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 48807fe760d5SStefano Zampini } 48817fe760d5SStefano Zampini 488275396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 488375396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 4884f5af7f23SKarl Rupp 4885454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 488603bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 48873a40ed3dSBarry Smith PetscFunctionReturn(0); 48889b94acceSBarry Smith } 48899b94acceSBarry Smith 48909b94acceSBarry Smith /*@C 48919a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 48929b94acceSBarry Smith 4893c7afd0dbSLois Curfman McInnes Not Collective 4894c7afd0dbSLois Curfman McInnes 48959b94acceSBarry Smith Input Parameter: 48964b0e389bSBarry Smith . snes - nonlinear solver context 48979b94acceSBarry Smith 48989b94acceSBarry Smith Output Parameter: 48993a7fca6bSBarry Smith . type - SNES method (a character string) 49009b94acceSBarry Smith 490136851e7fSLois Curfman McInnes Level: intermediate 490236851e7fSLois Curfman McInnes 49039b94acceSBarry Smith @*/ 490419fd82e9SBarry Smith PetscErrorCode SNESGetType(SNES snes,SNESType *type) 49059b94acceSBarry Smith { 49063a40ed3dSBarry Smith PetscFunctionBegin; 49070700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 49084482741eSBarry Smith PetscValidPointer(type,2); 49097adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 49103a40ed3dSBarry Smith PetscFunctionReturn(0); 49119b94acceSBarry Smith } 49129b94acceSBarry Smith 49133cd8a7caSMatthew G. Knepley /*@ 49143cd8a7caSMatthew G. Knepley SNESSetSolution - Sets the solution vector for use by the SNES routines. 49153cd8a7caSMatthew G. Knepley 4916d083f849SBarry Smith Logically Collective on SNES 49173cd8a7caSMatthew G. Knepley 49183cd8a7caSMatthew G. Knepley Input Parameters: 49193cd8a7caSMatthew G. Knepley + snes - the SNES context obtained from SNESCreate() 49203cd8a7caSMatthew G. Knepley - u - the solution vector 49213cd8a7caSMatthew G. Knepley 49223cd8a7caSMatthew G. Knepley Level: beginner 49233cd8a7caSMatthew G. Knepley 49243cd8a7caSMatthew G. Knepley @*/ 49253cd8a7caSMatthew G. Knepley PetscErrorCode SNESSetSolution(SNES snes, Vec u) 49263cd8a7caSMatthew G. Knepley { 49273cd8a7caSMatthew G. Knepley DM dm; 49283cd8a7caSMatthew G. Knepley PetscErrorCode ierr; 49293cd8a7caSMatthew G. Knepley 49303cd8a7caSMatthew G. Knepley PetscFunctionBegin; 49313cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 49323cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 49333cd8a7caSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) u);CHKERRQ(ierr); 49343cd8a7caSMatthew G. Knepley ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 49353cd8a7caSMatthew G. Knepley 49363cd8a7caSMatthew G. Knepley snes->vec_sol = u; 49373cd8a7caSMatthew G. Knepley 49383cd8a7caSMatthew G. Knepley ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 49393cd8a7caSMatthew G. Knepley ierr = DMShellSetGlobalVector(dm, u);CHKERRQ(ierr); 49403cd8a7caSMatthew G. Knepley PetscFunctionReturn(0); 49413cd8a7caSMatthew G. Knepley } 49423cd8a7caSMatthew G. Knepley 494352baeb72SSatish Balay /*@ 49449b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 4945c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 49469b94acceSBarry Smith 4947c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 4948c7afd0dbSLois Curfman McInnes 49499b94acceSBarry Smith Input Parameter: 49509b94acceSBarry Smith . snes - the SNES context 49519b94acceSBarry Smith 49529b94acceSBarry Smith Output Parameter: 49539b94acceSBarry Smith . x - the solution 49549b94acceSBarry Smith 495570e92668SMatthew Knepley Level: intermediate 495636851e7fSLois Curfman McInnes 495785385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 49589b94acceSBarry Smith @*/ 49597087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 49609b94acceSBarry Smith { 49613a40ed3dSBarry Smith PetscFunctionBegin; 49620700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 49634482741eSBarry Smith PetscValidPointer(x,2); 496485385478SLisandro Dalcin *x = snes->vec_sol; 496570e92668SMatthew Knepley PetscFunctionReturn(0); 496670e92668SMatthew Knepley } 496770e92668SMatthew Knepley 496852baeb72SSatish Balay /*@ 49699b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 49709b94acceSBarry Smith stored. 49719b94acceSBarry Smith 4972c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 4973c7afd0dbSLois Curfman McInnes 49749b94acceSBarry Smith Input Parameter: 49759b94acceSBarry Smith . snes - the SNES context 49769b94acceSBarry Smith 49779b94acceSBarry Smith Output Parameter: 49789b94acceSBarry Smith . x - the solution update 49799b94acceSBarry Smith 498036851e7fSLois Curfman McInnes Level: advanced 498136851e7fSLois Curfman McInnes 498285385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 49839b94acceSBarry Smith @*/ 49847087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 49859b94acceSBarry Smith { 49863a40ed3dSBarry Smith PetscFunctionBegin; 49870700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 49884482741eSBarry Smith PetscValidPointer(x,2); 498985385478SLisandro Dalcin *x = snes->vec_sol_update; 49903a40ed3dSBarry Smith PetscFunctionReturn(0); 49919b94acceSBarry Smith } 49929b94acceSBarry Smith 49939b94acceSBarry Smith /*@C 49943638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 49959b94acceSBarry Smith 4996a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 4997c7afd0dbSLois Curfman McInnes 49989b94acceSBarry Smith Input Parameter: 49999b94acceSBarry Smith . snes - the SNES context 50009b94acceSBarry Smith 50019b94acceSBarry Smith Output Parameter: 50020298fd71SBarry Smith + r - the vector that is used to store residuals (or NULL if you don't want it) 5003f8b49ee9SBarry Smith . f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details 50040298fd71SBarry Smith - ctx - the function context (or NULL if you don't want it) 50059b94acceSBarry Smith 500636851e7fSLois Curfman McInnes Level: advanced 500736851e7fSLois Curfman McInnes 500804edfde5SBarry Smith Notes: The vector r DOES NOT, in general contain the current value of the SNES nonlinear function 500904edfde5SBarry Smith 5010bf388a1fSBarry Smith .seealso: SNESSetFunction(), SNESGetSolution(), SNESFunction 50119b94acceSBarry Smith @*/ 5012f8b49ee9SBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx) 50139b94acceSBarry Smith { 5014a63bb30eSJed Brown PetscErrorCode ierr; 50156cab3a1bSJed Brown DM dm; 5016a63bb30eSJed Brown 50173a40ed3dSBarry Smith PetscFunctionBegin; 50180700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5019a63bb30eSJed Brown if (r) { 5020a63bb30eSJed Brown if (!snes->vec_func) { 5021a63bb30eSJed Brown if (snes->vec_rhs) { 5022a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 5023a63bb30eSJed Brown } else if (snes->vec_sol) { 5024a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 5025a63bb30eSJed Brown } else if (snes->dm) { 5026a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 5027a63bb30eSJed Brown } 5028a63bb30eSJed Brown } 5029a63bb30eSJed Brown *r = snes->vec_func; 5030a63bb30eSJed Brown } 50316cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 5032f8b49ee9SBarry Smith ierr = DMSNESGetFunction(dm,f,ctx);CHKERRQ(ierr); 50333a40ed3dSBarry Smith PetscFunctionReturn(0); 50349b94acceSBarry Smith } 50359b94acceSBarry Smith 5036c79ef259SPeter Brune /*@C 5037be95d8f1SBarry Smith SNESGetNGS - Returns the NGS function and context. 5038c79ef259SPeter Brune 5039c79ef259SPeter Brune Input Parameter: 5040c79ef259SPeter Brune . snes - the SNES context 5041c79ef259SPeter Brune 5042c79ef259SPeter Brune Output Parameter: 5043be95d8f1SBarry Smith + f - the function (or NULL) see SNESNGSFunction for details 50440298fd71SBarry Smith - ctx - the function context (or NULL) 5045c79ef259SPeter Brune 5046c79ef259SPeter Brune Level: advanced 5047c79ef259SPeter Brune 5048be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESGetFunction() 5049c79ef259SPeter Brune @*/ 5050c79ef259SPeter Brune 5051be95d8f1SBarry Smith PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx) 5052646217ecSPeter Brune { 50536cab3a1bSJed Brown PetscErrorCode ierr; 50546cab3a1bSJed Brown DM dm; 50556cab3a1bSJed Brown 5056646217ecSPeter Brune PetscFunctionBegin; 5057646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 50586cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 5059be95d8f1SBarry Smith ierr = DMSNESGetNGS(dm,f,ctx);CHKERRQ(ierr); 5060646217ecSPeter Brune PetscFunctionReturn(0); 5061646217ecSPeter Brune } 5062646217ecSPeter Brune 50633c7409f5SSatish Balay /*@C 50643c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 5065d850072dSLois Curfman McInnes SNES options in the database. 50663c7409f5SSatish Balay 50673f9fe445SBarry Smith Logically Collective on SNES 5068fee21e36SBarry Smith 5069c7afd0dbSLois Curfman McInnes Input Parameter: 5070c7afd0dbSLois Curfman McInnes + snes - the SNES context 5071c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 5072c7afd0dbSLois Curfman McInnes 5073d850072dSLois Curfman McInnes Notes: 5074a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 5075c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 5076d850072dSLois Curfman McInnes 507736851e7fSLois Curfman McInnes Level: advanced 507836851e7fSLois Curfman McInnes 5079a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 50803c7409f5SSatish Balay @*/ 50817087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 50823c7409f5SSatish Balay { 5083dfbe8321SBarry Smith PetscErrorCode ierr; 50843c7409f5SSatish Balay 50853a40ed3dSBarry Smith PetscFunctionBegin; 50860700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5087639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 50881cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 508935f5d045SPeter Brune if (snes->linesearch) { 50907601faf0SJed Brown ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 509108b6c495SPeter Brune ierr = PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 509235f5d045SPeter Brune } 509335f5d045SPeter Brune ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 50943a40ed3dSBarry Smith PetscFunctionReturn(0); 50953c7409f5SSatish Balay } 50963c7409f5SSatish Balay 50973c7409f5SSatish Balay /*@C 5098f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 5099d850072dSLois Curfman McInnes SNES options in the database. 51003c7409f5SSatish Balay 51013f9fe445SBarry Smith Logically Collective on SNES 5102fee21e36SBarry Smith 5103c7afd0dbSLois Curfman McInnes Input Parameters: 5104c7afd0dbSLois Curfman McInnes + snes - the SNES context 5105c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 5106c7afd0dbSLois Curfman McInnes 5107d850072dSLois Curfman McInnes Notes: 5108a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 5109c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 5110d850072dSLois Curfman McInnes 511136851e7fSLois Curfman McInnes Level: advanced 511236851e7fSLois Curfman McInnes 5113a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 51143c7409f5SSatish Balay @*/ 51157087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 51163c7409f5SSatish Balay { 5117dfbe8321SBarry Smith PetscErrorCode ierr; 51183c7409f5SSatish Balay 51193a40ed3dSBarry Smith PetscFunctionBegin; 51200700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5121639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 51221cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 512335f5d045SPeter Brune if (snes->linesearch) { 51247601faf0SJed Brown ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 512508b6c495SPeter Brune ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 512635f5d045SPeter Brune } 512735f5d045SPeter Brune ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 51283a40ed3dSBarry Smith PetscFunctionReturn(0); 51293c7409f5SSatish Balay } 51303c7409f5SSatish Balay 51319ab63eb5SSatish Balay /*@C 51323c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 51333c7409f5SSatish Balay SNES options in the database. 51343c7409f5SSatish Balay 5135c7afd0dbSLois Curfman McInnes Not Collective 5136c7afd0dbSLois Curfman McInnes 51373c7409f5SSatish Balay Input Parameter: 51383c7409f5SSatish Balay . snes - the SNES context 51393c7409f5SSatish Balay 51403c7409f5SSatish Balay Output Parameter: 51413c7409f5SSatish Balay . prefix - pointer to the prefix string used 51423c7409f5SSatish Balay 514395452b02SPatrick Sanan Notes: 514495452b02SPatrick Sanan On the fortran side, the user should pass in a string 'prefix' of 51459ab63eb5SSatish Balay sufficient length to hold the prefix. 51469ab63eb5SSatish Balay 514736851e7fSLois Curfman McInnes Level: advanced 514836851e7fSLois Curfman McInnes 5149a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 51503c7409f5SSatish Balay @*/ 51517087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 51523c7409f5SSatish Balay { 5153dfbe8321SBarry Smith PetscErrorCode ierr; 51543c7409f5SSatish Balay 51553a40ed3dSBarry Smith PetscFunctionBegin; 51560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5157639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 51583a40ed3dSBarry Smith PetscFunctionReturn(0); 51593c7409f5SSatish Balay } 51603c7409f5SSatish Balay 5161b2002411SLois Curfman McInnes 51623cea93caSBarry Smith /*@C 51631c84c290SBarry Smith SNESRegister - Adds a method to the nonlinear solver package. 51641c84c290SBarry Smith 51651c84c290SBarry Smith Not collective 51661c84c290SBarry Smith 51671c84c290SBarry Smith Input Parameters: 51681c84c290SBarry Smith + name_solver - name of a new user-defined solver 51691c84c290SBarry Smith - routine_create - routine to create method context 51701c84c290SBarry Smith 51711c84c290SBarry Smith Notes: 51721c84c290SBarry Smith SNESRegister() may be called multiple times to add several user-defined solvers. 51731c84c290SBarry Smith 51741c84c290SBarry Smith Sample usage: 51751c84c290SBarry Smith .vb 5176bdf89e91SBarry Smith SNESRegister("my_solver",MySolverCreate); 51771c84c290SBarry Smith .ve 51781c84c290SBarry Smith 51791c84c290SBarry Smith Then, your solver can be chosen with the procedural interface via 51801c84c290SBarry Smith $ SNESSetType(snes,"my_solver") 51811c84c290SBarry Smith or at runtime via the option 51821c84c290SBarry Smith $ -snes_type my_solver 51831c84c290SBarry Smith 51841c84c290SBarry Smith Level: advanced 51851c84c290SBarry Smith 51861c84c290SBarry Smith Note: If your function is not being put into a shared library then use SNESRegister() instead 51871c84c290SBarry Smith 51881c84c290SBarry Smith .seealso: SNESRegisterAll(), SNESRegisterDestroy() 51893cea93caSBarry Smith 51907f6c08e0SMatthew Knepley Level: advanced 51913cea93caSBarry Smith @*/ 5192bdf89e91SBarry Smith PetscErrorCode SNESRegister(const char sname[],PetscErrorCode (*function)(SNES)) 5193b2002411SLois Curfman McInnes { 5194dfbe8321SBarry Smith PetscErrorCode ierr; 5195b2002411SLois Curfman McInnes 5196b2002411SLois Curfman McInnes PetscFunctionBegin; 51971d36bdfdSBarry Smith ierr = SNESInitializePackage();CHKERRQ(ierr); 5198a240a19fSJed Brown ierr = PetscFunctionListAdd(&SNESList,sname,function);CHKERRQ(ierr); 5199b2002411SLois Curfman McInnes PetscFunctionReturn(0); 5200b2002411SLois Curfman McInnes } 5201da9b6338SBarry Smith 52027087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 5203da9b6338SBarry Smith { 5204dfbe8321SBarry Smith PetscErrorCode ierr; 520577431f27SBarry Smith PetscInt N,i,j; 5206da9b6338SBarry Smith Vec u,uh,fh; 5207da9b6338SBarry Smith PetscScalar value; 5208da9b6338SBarry Smith PetscReal norm; 5209da9b6338SBarry Smith 5210da9b6338SBarry Smith PetscFunctionBegin; 5211da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 5212da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 5213da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 5214da9b6338SBarry Smith 5215da9b6338SBarry Smith /* currently only works for sequential */ 5216ea13f565SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"Testing FormFunction() for local min\n");CHKERRQ(ierr); 5217da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 5218da9b6338SBarry Smith for (i=0; i<N; i++) { 5219da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 5220ea13f565SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"i = %D\n",i);CHKERRQ(ierr); 5221da9b6338SBarry Smith for (j=-10; j<11; j++) { 52228b49ba18SBarry Smith value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0); 5223da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 52243ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 5225da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 5226ea13f565SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)snes)," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 5227da9b6338SBarry Smith value = -value; 5228da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 5229da9b6338SBarry Smith } 5230da9b6338SBarry Smith } 52316bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 52326bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 5233da9b6338SBarry Smith PetscFunctionReturn(0); 5234da9b6338SBarry Smith } 523571f87433Sdalcinl 523671f87433Sdalcinl /*@ 5237fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 523871f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 523971f87433Sdalcinl Newton method. 524071f87433Sdalcinl 52413f9fe445SBarry Smith Logically Collective on SNES 524271f87433Sdalcinl 524371f87433Sdalcinl Input Parameters: 524471f87433Sdalcinl + snes - SNES context 524571f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 524671f87433Sdalcinl 524764ba62caSBarry Smith Options Database: 524864ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 524964ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 525064ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 525164ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 525264ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 525364ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 525464ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 525564ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 525664ba62caSBarry Smith 525771f87433Sdalcinl Notes: 525871f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 525971f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 526071f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 526171f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 526271f87433Sdalcinl solver. 526371f87433Sdalcinl 526471f87433Sdalcinl Level: advanced 526571f87433Sdalcinl 526671f87433Sdalcinl Reference: 526771f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 526871f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 526971f87433Sdalcinl 5270fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 527171f87433Sdalcinl @*/ 52727087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 527371f87433Sdalcinl { 527471f87433Sdalcinl PetscFunctionBegin; 52750700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5276acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 527771f87433Sdalcinl snes->ksp_ewconv = flag; 527871f87433Sdalcinl PetscFunctionReturn(0); 527971f87433Sdalcinl } 528071f87433Sdalcinl 528171f87433Sdalcinl /*@ 5282fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 528371f87433Sdalcinl for computing relative tolerance for linear solvers within an 528471f87433Sdalcinl inexact Newton method. 528571f87433Sdalcinl 528671f87433Sdalcinl Not Collective 528771f87433Sdalcinl 528871f87433Sdalcinl Input Parameter: 528971f87433Sdalcinl . snes - SNES context 529071f87433Sdalcinl 529171f87433Sdalcinl Output Parameter: 529271f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 529371f87433Sdalcinl 529471f87433Sdalcinl Notes: 529571f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 529671f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 529771f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 529871f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 529971f87433Sdalcinl solver. 530071f87433Sdalcinl 530171f87433Sdalcinl Level: advanced 530271f87433Sdalcinl 530371f87433Sdalcinl Reference: 530471f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 530571f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 530671f87433Sdalcinl 5307fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 530871f87433Sdalcinl @*/ 53097087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 531071f87433Sdalcinl { 531171f87433Sdalcinl PetscFunctionBegin; 53120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5313534a8f05SLisandro Dalcin PetscValidBoolPointer(flag,2); 531471f87433Sdalcinl *flag = snes->ksp_ewconv; 531571f87433Sdalcinl PetscFunctionReturn(0); 531671f87433Sdalcinl } 531771f87433Sdalcinl 531871f87433Sdalcinl /*@ 5319fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 532071f87433Sdalcinl convergence criteria for the linear solvers within an inexact 532171f87433Sdalcinl Newton method. 532271f87433Sdalcinl 53233f9fe445SBarry Smith Logically Collective on SNES 532471f87433Sdalcinl 532571f87433Sdalcinl Input Parameters: 532671f87433Sdalcinl + snes - SNES context 532771f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 532871f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 532971f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 533071f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 533171f87433Sdalcinl (0 <= gamma2 <= 1) 533271f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 533371f87433Sdalcinl . alpha2 - power for safeguard 533471f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 533571f87433Sdalcinl 533671f87433Sdalcinl Note: 533771f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 533871f87433Sdalcinl 533971f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 534071f87433Sdalcinl 534171f87433Sdalcinl Level: advanced 534271f87433Sdalcinl 534371f87433Sdalcinl Reference: 534471f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 534571f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 534671f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 534771f87433Sdalcinl 5348fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 534971f87433Sdalcinl @*/ 5350f5af7f23SKarl Rupp PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 535171f87433Sdalcinl { 5352fa9f3622SBarry Smith SNESKSPEW *kctx; 53535fd66863SKarl Rupp 535471f87433Sdalcinl PetscFunctionBegin; 53550700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5356fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 5357e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 5358c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 5359c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 5360c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 5361c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 5362c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 5363c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 5364c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 536571f87433Sdalcinl 536671f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 536771f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 536871f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 536971f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 537071f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 537171f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 537271f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 537371f87433Sdalcinl 5374f23aa3ddSBarry 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); 537557622a8eSBarry 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); 537657622a8eSBarry 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); 537757622a8eSBarry 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); 537857622a8eSBarry 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); 537957622a8eSBarry 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); 538071f87433Sdalcinl PetscFunctionReturn(0); 538171f87433Sdalcinl } 538271f87433Sdalcinl 538371f87433Sdalcinl /*@ 5384fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 538571f87433Sdalcinl convergence criteria for the linear solvers within an inexact 538671f87433Sdalcinl Newton method. 538771f87433Sdalcinl 538871f87433Sdalcinl Not Collective 538971f87433Sdalcinl 539071f87433Sdalcinl Input Parameters: 539171f87433Sdalcinl snes - SNES context 539271f87433Sdalcinl 539371f87433Sdalcinl Output Parameters: 539471f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 539571f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 539671f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 5397bf388a1fSBarry Smith . gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1) 539871f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 539971f87433Sdalcinl . alpha2 - power for safeguard 540071f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 540171f87433Sdalcinl 540271f87433Sdalcinl Level: advanced 540371f87433Sdalcinl 5404fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 540571f87433Sdalcinl @*/ 5406bf388a1fSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 540771f87433Sdalcinl { 5408fa9f3622SBarry Smith SNESKSPEW *kctx; 54095fd66863SKarl Rupp 541071f87433Sdalcinl PetscFunctionBegin; 54110700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5412fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 5413e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 541471f87433Sdalcinl if (version) *version = kctx->version; 541571f87433Sdalcinl if (rtol_0) *rtol_0 = kctx->rtol_0; 541671f87433Sdalcinl if (rtol_max) *rtol_max = kctx->rtol_max; 541771f87433Sdalcinl if (gamma) *gamma = kctx->gamma; 541871f87433Sdalcinl if (alpha) *alpha = kctx->alpha; 541971f87433Sdalcinl if (alpha2) *alpha2 = kctx->alpha2; 542071f87433Sdalcinl if (threshold) *threshold = kctx->threshold; 542171f87433Sdalcinl PetscFunctionReturn(0); 542271f87433Sdalcinl } 542371f87433Sdalcinl 5424d5378b5fSDmitry Karpeev PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 542571f87433Sdalcinl { 542671f87433Sdalcinl PetscErrorCode ierr; 5427fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 542871f87433Sdalcinl PetscReal rtol = PETSC_DEFAULT,stol; 542971f87433Sdalcinl 543071f87433Sdalcinl PetscFunctionBegin; 5431d4211eb9SBarry Smith if (!snes->ksp_ewconv) PetscFunctionReturn(0); 543230058271SDmitry Karpeev if (!snes->iter) { 543330058271SDmitry Karpeev rtol = kctx->rtol_0; /* first time in, so use the original user rtol */ 543430058271SDmitry Karpeev ierr = VecNorm(snes->vec_func,NORM_2,&kctx->norm_first);CHKERRQ(ierr); 543530058271SDmitry Karpeev } 5436f5af7f23SKarl Rupp else { 543771f87433Sdalcinl if (kctx->version == 1) { 543871f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 543971f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 544085ec1a3cSBarry Smith stol = PetscPowReal(kctx->rtol_last,kctx->alpha2); 544171f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 544271f87433Sdalcinl } else if (kctx->version == 2) { 544385ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 544485ec1a3cSBarry Smith stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha); 544571f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 544671f87433Sdalcinl } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */ 544785ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 544871f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 544985ec1a3cSBarry Smith stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha); 545071f87433Sdalcinl stol = PetscMax(rtol,stol); 545171f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 545271f87433Sdalcinl /* safeguard: avoid oversolving */ 545330058271SDmitry Karpeev stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm; 545471f87433Sdalcinl stol = PetscMax(rtol,stol); 545571f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 5456e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 545771f87433Sdalcinl } 545871f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 545971f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 546071f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 546157622a8eSBarry Smith ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol);CHKERRQ(ierr); 546271f87433Sdalcinl PetscFunctionReturn(0); 546371f87433Sdalcinl } 546471f87433Sdalcinl 5465d5378b5fSDmitry Karpeev PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 546671f87433Sdalcinl { 546771f87433Sdalcinl PetscErrorCode ierr; 5468fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 546971f87433Sdalcinl PCSide pcside; 547071f87433Sdalcinl Vec lres; 547171f87433Sdalcinl 547271f87433Sdalcinl PetscFunctionBegin; 5473d4211eb9SBarry Smith if (!snes->ksp_ewconv) PetscFunctionReturn(0); 54749e5d0892SLisandro Dalcin ierr = KSPGetTolerances(ksp,&kctx->rtol_last,NULL,NULL,NULL);CHKERRQ(ierr); 547571dbe336SPeter Brune kctx->norm_last = snes->norm; 547671f87433Sdalcinl if (kctx->version == 1) { 54774f00ce20SMatthew G. Knepley PC pc; 54784f00ce20SMatthew G. Knepley PetscBool isNone; 54794f00ce20SMatthew G. Knepley 54804f00ce20SMatthew G. Knepley ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr); 54814f00ce20SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) pc, PCNONE, &isNone);CHKERRQ(ierr); 5482b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 54834f00ce20SMatthew G. Knepley if (pcside == PC_RIGHT || isNone) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 548471f87433Sdalcinl /* KSP residual is true linear residual */ 548571f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 548671f87433Sdalcinl } else { 548771f87433Sdalcinl /* KSP residual is preconditioned residual */ 548871f87433Sdalcinl /* compute true linear residual norm */ 548971f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 549071f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 549171f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 549271f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 54936bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 549471f87433Sdalcinl } 549571f87433Sdalcinl } 549671f87433Sdalcinl PetscFunctionReturn(0); 549771f87433Sdalcinl } 549871f87433Sdalcinl 5499d4211eb9SBarry Smith /*@ 5500d4211eb9SBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 5501d4211eb9SBarry Smith 5502d4211eb9SBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 5503d4211eb9SBarry Smith 5504d4211eb9SBarry Smith Input Parameter: 5505d4211eb9SBarry Smith . snes - the SNES context 5506d4211eb9SBarry Smith 5507d4211eb9SBarry Smith Output Parameter: 5508d4211eb9SBarry Smith . ksp - the KSP context 5509d4211eb9SBarry Smith 5510d4211eb9SBarry Smith Notes: 5511d4211eb9SBarry Smith The user can then directly manipulate the KSP context to set various 5512d4211eb9SBarry Smith options, etc. Likewise, the user can then extract and manipulate the 5513d4211eb9SBarry Smith PC contexts as well. 5514d4211eb9SBarry Smith 5515d4211eb9SBarry Smith Level: beginner 5516d4211eb9SBarry Smith 5517d4211eb9SBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 5518d4211eb9SBarry Smith @*/ 5519d4211eb9SBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 552071f87433Sdalcinl { 552171f87433Sdalcinl PetscErrorCode ierr; 552271f87433Sdalcinl 552371f87433Sdalcinl PetscFunctionBegin; 5524d4211eb9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5525d4211eb9SBarry Smith PetscValidPointer(ksp,2); 5526d4211eb9SBarry Smith 5527d4211eb9SBarry Smith if (!snes->ksp) { 5528d4211eb9SBarry Smith ierr = KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp);CHKERRQ(ierr); 5529d4211eb9SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 55303bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp);CHKERRQ(ierr); 5531d4211eb9SBarry Smith 5532d5378b5fSDmitry Karpeev ierr = KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes);CHKERRQ(ierr); 5533d5378b5fSDmitry Karpeev ierr = KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes);CHKERRQ(ierr); 5534a5c2985bSBarry Smith 5535798534f6SMatthew G. Knepley ierr = KSPMonitorSetFromOptions(snes->ksp, "-snes_monitor_ksp", "snes_preconditioned_residual", snes);CHKERRQ(ierr); 553616413a6aSBarry Smith ierr = PetscObjectSetOptions((PetscObject)snes->ksp,((PetscObject)snes)->options);CHKERRQ(ierr); 5537d4211eb9SBarry Smith } 5538d4211eb9SBarry Smith *ksp = snes->ksp; 553971f87433Sdalcinl PetscFunctionReturn(0); 554071f87433Sdalcinl } 55416c699258SBarry Smith 5542d4211eb9SBarry Smith 5543af0996ceSBarry Smith #include <petsc/private/dmimpl.h> 55446c699258SBarry Smith /*@ 55452a808120SBarry Smith SNESSetDM - Sets the DM that may be used by some nonlinear solvers or their underlying preconditioners 55466c699258SBarry Smith 55473f9fe445SBarry Smith Logically Collective on SNES 55486c699258SBarry Smith 55496c699258SBarry Smith Input Parameters: 55502a808120SBarry Smith + snes - the nonlinear solver context 55512a808120SBarry Smith - dm - the dm, cannot be NULL 55526c699258SBarry Smith 5553e03a659cSJed Brown Notes: 5554e03a659cSJed Brown A DM can only be used for solving one problem at a time because information about the problem is stored on the DM, 5555e03a659cSJed Brown even when not using interfaces like DMSNESSetFunction(). Use DMClone() to get a distinct DM when solving different 5556e03a659cSJed Brown problems using the same function space. 5557e03a659cSJed Brown 55586c699258SBarry Smith Level: intermediate 55596c699258SBarry Smith 55604c2026ceSFande Kong .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 55616c699258SBarry Smith @*/ 55627087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 55636c699258SBarry Smith { 55646c699258SBarry Smith PetscErrorCode ierr; 5565345fed2cSBarry Smith KSP ksp; 5566942e3340SBarry Smith DMSNES sdm; 55676c699258SBarry Smith 55686c699258SBarry Smith PetscFunctionBegin; 55690700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 55702a808120SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,2); 55712a808120SBarry Smith ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 5572942e3340SBarry Smith if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */ 557351f4b3c7SToby Isaac if (snes->dm->dmsnes && !dm->dmsnes) { 5574942e3340SBarry Smith ierr = DMCopyDMSNES(snes->dm,dm);CHKERRQ(ierr); 5575942e3340SBarry Smith ierr = DMGetDMSNES(snes->dm,&sdm);CHKERRQ(ierr); 5576f5af7f23SKarl Rupp if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */ 55776cab3a1bSJed Brown } 5578dc822a44SJed Brown ierr = DMCoarsenHookRemove(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 55796bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 55806cab3a1bSJed Brown } 55816c699258SBarry Smith snes->dm = dm; 5582116d1032SJed Brown snes->dmAuto = PETSC_FALSE; 5583f5af7f23SKarl Rupp 5584345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 5585345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 5586f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 5587efd4aadfSBarry Smith if (snes->npc) { 5588efd4aadfSBarry Smith ierr = SNESSetDM(snes->npc, snes->dm);CHKERRQ(ierr); 5589efd4aadfSBarry Smith ierr = SNESSetNPCSide(snes,snes->npcside);CHKERRQ(ierr); 55902c155ee1SBarry Smith } 55916c699258SBarry Smith PetscFunctionReturn(0); 55926c699258SBarry Smith } 55936c699258SBarry Smith 55946c699258SBarry Smith /*@ 55956c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 55966c699258SBarry Smith 55973f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 55986c699258SBarry Smith 55996c699258SBarry Smith Input Parameter: 56006c699258SBarry Smith . snes - the preconditioner context 56016c699258SBarry Smith 56026c699258SBarry Smith Output Parameter: 56036c699258SBarry Smith . dm - the dm 56046c699258SBarry Smith 56056c699258SBarry Smith Level: intermediate 56066c699258SBarry Smith 56074c2026ceSFande Kong .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 56086c699258SBarry Smith @*/ 56097087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 56106c699258SBarry Smith { 56116cab3a1bSJed Brown PetscErrorCode ierr; 56126cab3a1bSJed Brown 56136c699258SBarry Smith PetscFunctionBegin; 56140700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 56156cab3a1bSJed Brown if (!snes->dm) { 5616ce94432eSBarry Smith ierr = DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm);CHKERRQ(ierr); 5617116d1032SJed Brown snes->dmAuto = PETSC_TRUE; 56186cab3a1bSJed Brown } 56196c699258SBarry Smith *dm = snes->dm; 56206c699258SBarry Smith PetscFunctionReturn(0); 56216c699258SBarry Smith } 56220807856dSBarry Smith 562331823bd8SMatthew G Knepley /*@ 5624be95d8f1SBarry Smith SNESSetNPC - Sets the nonlinear preconditioner to be used. 562531823bd8SMatthew G Knepley 562631823bd8SMatthew G Knepley Collective on SNES 562731823bd8SMatthew G Knepley 562831823bd8SMatthew G Knepley Input Parameters: 562931823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 563031823bd8SMatthew G Knepley - pc - the preconditioner object 563131823bd8SMatthew G Knepley 563231823bd8SMatthew G Knepley Notes: 5633be95d8f1SBarry Smith Use SNESGetNPC() to retrieve the preconditioner context (for example, 563431823bd8SMatthew G Knepley to configure it using the API). 563531823bd8SMatthew G Knepley 563631823bd8SMatthew G Knepley Level: developer 563731823bd8SMatthew G Knepley 56383ad1a0b9SPatrick Farrell .seealso: SNESGetNPC(), SNESHasNPC() 563931823bd8SMatthew G Knepley @*/ 5640be95d8f1SBarry Smith PetscErrorCode SNESSetNPC(SNES snes, SNES pc) 564131823bd8SMatthew G Knepley { 564231823bd8SMatthew G Knepley PetscErrorCode ierr; 564331823bd8SMatthew G Knepley 564431823bd8SMatthew G Knepley PetscFunctionBegin; 564531823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 564631823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 564731823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 564831823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 5649efd4aadfSBarry Smith ierr = SNESDestroy(&snes->npc);CHKERRQ(ierr); 5650efd4aadfSBarry Smith snes->npc = pc; 5651efd4aadfSBarry Smith ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->npc);CHKERRQ(ierr); 565231823bd8SMatthew G Knepley PetscFunctionReturn(0); 565331823bd8SMatthew G Knepley } 565431823bd8SMatthew G Knepley 565531823bd8SMatthew G Knepley /*@ 5656be95d8f1SBarry Smith SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver. 565731823bd8SMatthew G Knepley 5658951fe5abSBarry Smith Not Collective; but any changes to the obtained SNES object must be applied collectively 565931823bd8SMatthew G Knepley 566031823bd8SMatthew G Knepley Input Parameter: 566131823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 566231823bd8SMatthew G Knepley 566331823bd8SMatthew G Knepley Output Parameter: 566431823bd8SMatthew G Knepley . pc - preconditioner context 566531823bd8SMatthew G Knepley 5666b5badacbSBarry Smith Options Database: 5667b5badacbSBarry Smith . -npc_snes_type <type> - set the type of the SNES to use as the nonlinear preconditioner 5668b5badacbSBarry Smith 566995452b02SPatrick Sanan Notes: 5670b5badacbSBarry Smith If a SNES was previously set with SNESSetNPC() then that SNES is returned, otherwise a new SNES object is created. 5671be95d8f1SBarry Smith 5672951fe5abSBarry Smith The (preconditioner) SNES returned automatically inherits the same nonlinear function and Jacobian supplied to the original 5673951fe5abSBarry Smith SNES during SNESSetUp() 5674951fe5abSBarry Smith 567531823bd8SMatthew G Knepley Level: developer 567631823bd8SMatthew G Knepley 5677951fe5abSBarry Smith .seealso: SNESSetNPC(), SNESHasNPC(), SNES, SNESCreate() 567831823bd8SMatthew G Knepley @*/ 5679be95d8f1SBarry Smith PetscErrorCode SNESGetNPC(SNES snes, SNES *pc) 568031823bd8SMatthew G Knepley { 568131823bd8SMatthew G Knepley PetscErrorCode ierr; 5682a64e098fSPeter Brune const char *optionsprefix; 568331823bd8SMatthew G Knepley 568431823bd8SMatthew G Knepley PetscFunctionBegin; 568531823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 568631823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 5687efd4aadfSBarry Smith if (!snes->npc) { 5688efd4aadfSBarry Smith ierr = SNESCreate(PetscObjectComm((PetscObject)snes),&snes->npc);CHKERRQ(ierr); 5689efd4aadfSBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->npc,(PetscObject)snes,1);CHKERRQ(ierr); 5690efd4aadfSBarry Smith ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr); 5691a64e098fSPeter Brune ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr); 5692efd4aadfSBarry Smith ierr = SNESSetOptionsPrefix(snes->npc,optionsprefix);CHKERRQ(ierr); 5693efd4aadfSBarry Smith ierr = SNESAppendOptionsPrefix(snes->npc,"npc_");CHKERRQ(ierr); 5694efd4aadfSBarry Smith ierr = SNESSetCountersReset(snes->npc,PETSC_FALSE);CHKERRQ(ierr); 569531823bd8SMatthew G Knepley } 5696efd4aadfSBarry Smith *pc = snes->npc; 569731823bd8SMatthew G Knepley PetscFunctionReturn(0); 569831823bd8SMatthew G Knepley } 569931823bd8SMatthew G Knepley 57003ad1a0b9SPatrick Farrell /*@ 57013ad1a0b9SPatrick Farrell SNESHasNPC - Returns whether a nonlinear preconditioner exists 57023ad1a0b9SPatrick Farrell 57033ad1a0b9SPatrick Farrell Not Collective 57043ad1a0b9SPatrick Farrell 57053ad1a0b9SPatrick Farrell Input Parameter: 57063ad1a0b9SPatrick Farrell . snes - iterative context obtained from SNESCreate() 57073ad1a0b9SPatrick Farrell 57083ad1a0b9SPatrick Farrell Output Parameter: 57093ad1a0b9SPatrick Farrell . has_npc - whether the SNES has an NPC or not 57103ad1a0b9SPatrick Farrell 57113ad1a0b9SPatrick Farrell Level: developer 57123ad1a0b9SPatrick Farrell 57133ad1a0b9SPatrick Farrell .seealso: SNESSetNPC(), SNESGetNPC() 57143ad1a0b9SPatrick Farrell @*/ 57153ad1a0b9SPatrick Farrell PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc) 57163ad1a0b9SPatrick Farrell { 57173ad1a0b9SPatrick Farrell PetscFunctionBegin; 57183ad1a0b9SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5719efd4aadfSBarry Smith *has_npc = (PetscBool) (snes->npc ? PETSC_TRUE : PETSC_FALSE); 57203ad1a0b9SPatrick Farrell PetscFunctionReturn(0); 57213ad1a0b9SPatrick Farrell } 57223ad1a0b9SPatrick Farrell 5723c40d0f55SPeter Brune /*@ 5724be95d8f1SBarry Smith SNESSetNPCSide - Sets the preconditioning side. 5725c40d0f55SPeter Brune 5726c40d0f55SPeter Brune Logically Collective on SNES 5727c40d0f55SPeter Brune 5728c40d0f55SPeter Brune Input Parameter: 5729c40d0f55SPeter Brune . snes - iterative context obtained from SNESCreate() 5730c40d0f55SPeter Brune 5731c40d0f55SPeter Brune Output Parameter: 5732c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5733c40d0f55SPeter Brune .vb 57342d547940SBarry Smith PC_LEFT - left preconditioning 57352d547940SBarry Smith PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5736c40d0f55SPeter Brune .ve 5737c40d0f55SPeter Brune 5738c40d0f55SPeter Brune Options Database Keys: 5739c40d0f55SPeter Brune . -snes_pc_side <right,left> 5740c40d0f55SPeter Brune 574195452b02SPatrick Sanan Notes: 574295452b02SPatrick Sanan SNESNRICHARDSON and SNESNCG only support left preconditioning. 57432d547940SBarry Smith 5744c40d0f55SPeter Brune Level: intermediate 5745c40d0f55SPeter Brune 5746be95d8f1SBarry Smith .seealso: SNESGetNPCSide(), KSPSetPCSide() 5747c40d0f55SPeter Brune @*/ 5748be95d8f1SBarry Smith PetscErrorCode SNESSetNPCSide(SNES snes,PCSide side) 5749c40d0f55SPeter Brune { 5750c40d0f55SPeter Brune PetscFunctionBegin; 5751c40d0f55SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5752c40d0f55SPeter Brune PetscValidLogicalCollectiveEnum(snes,side,2); 5753efd4aadfSBarry Smith snes->npcside= side; 5754c40d0f55SPeter Brune PetscFunctionReturn(0); 5755c40d0f55SPeter Brune } 5756c40d0f55SPeter Brune 5757c40d0f55SPeter Brune /*@ 5758be95d8f1SBarry Smith SNESGetNPCSide - Gets the preconditioning side. 5759c40d0f55SPeter Brune 5760c40d0f55SPeter Brune Not Collective 5761c40d0f55SPeter Brune 5762c40d0f55SPeter Brune Input Parameter: 5763c40d0f55SPeter Brune . snes - iterative context obtained from SNESCreate() 5764c40d0f55SPeter Brune 5765c40d0f55SPeter Brune Output Parameter: 5766c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5767c40d0f55SPeter Brune .vb 57682d547940SBarry Smith PC_LEFT - left preconditioning 57692d547940SBarry Smith PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5770c40d0f55SPeter Brune .ve 5771c40d0f55SPeter Brune 5772c40d0f55SPeter Brune Level: intermediate 5773c40d0f55SPeter Brune 5774be95d8f1SBarry Smith .seealso: SNESSetNPCSide(), KSPGetPCSide() 5775c40d0f55SPeter Brune @*/ 5776be95d8f1SBarry Smith PetscErrorCode SNESGetNPCSide(SNES snes,PCSide *side) 5777c40d0f55SPeter Brune { 5778c40d0f55SPeter Brune PetscFunctionBegin; 5779c40d0f55SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5780c40d0f55SPeter Brune PetscValidPointer(side,2); 5781efd4aadfSBarry Smith *side = snes->npcside; 5782c40d0f55SPeter Brune PetscFunctionReturn(0); 5783c40d0f55SPeter Brune } 5784c40d0f55SPeter Brune 57859e764e56SPeter Brune /*@ 57867601faf0SJed Brown SNESSetLineSearch - Sets the linesearch on the SNES instance. 57879e764e56SPeter Brune 57889e764e56SPeter Brune Collective on SNES 57899e764e56SPeter Brune 57909e764e56SPeter Brune Input Parameters: 57919e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 57929e764e56SPeter Brune - linesearch - the linesearch object 57939e764e56SPeter Brune 57949e764e56SPeter Brune Notes: 57957601faf0SJed Brown Use SNESGetLineSearch() to retrieve the preconditioner context (for example, 57969e764e56SPeter Brune to configure it using the API). 57979e764e56SPeter Brune 57989e764e56SPeter Brune Level: developer 57999e764e56SPeter Brune 58007601faf0SJed Brown .seealso: SNESGetLineSearch() 58019e764e56SPeter Brune @*/ 58027601faf0SJed Brown PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch) 58039e764e56SPeter Brune { 58049e764e56SPeter Brune PetscErrorCode ierr; 58059e764e56SPeter Brune 58069e764e56SPeter Brune PetscFunctionBegin; 58079e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5808f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 58099e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 58109e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 5811f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 5812f5af7f23SKarl Rupp 58139e764e56SPeter Brune snes->linesearch = linesearch; 5814f5af7f23SKarl Rupp 58153bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr); 58169e764e56SPeter Brune PetscFunctionReturn(0); 58179e764e56SPeter Brune } 58189e764e56SPeter Brune 5819a34ceb2aSJed Brown /*@ 58207601faf0SJed Brown SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 58218141a3b9SPeter Brune or creates a default line search instance associated with the SNES and returns it. 58229e764e56SPeter Brune 58239e764e56SPeter Brune Not Collective 58249e764e56SPeter Brune 58259e764e56SPeter Brune Input Parameter: 58269e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 58279e764e56SPeter Brune 58289e764e56SPeter Brune Output Parameter: 58299e764e56SPeter Brune . linesearch - linesearch context 58309e764e56SPeter Brune 5831162e0bf5SPeter Brune Level: beginner 58329e764e56SPeter Brune 5833162e0bf5SPeter Brune .seealso: SNESSetLineSearch(), SNESLineSearchCreate() 58349e764e56SPeter Brune @*/ 58357601faf0SJed Brown PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch) 58369e764e56SPeter Brune { 58379e764e56SPeter Brune PetscErrorCode ierr; 58389e764e56SPeter Brune const char *optionsprefix; 58399e764e56SPeter Brune 58409e764e56SPeter Brune PetscFunctionBegin; 58419e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 58429e764e56SPeter Brune PetscValidPointer(linesearch, 2); 58439e764e56SPeter Brune if (!snes->linesearch) { 58449e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 584582f516ccSBarry Smith ierr = SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch);CHKERRQ(ierr); 5846f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 5847b1dca40bSPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 58489e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 58493bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr); 58509e764e56SPeter Brune } 58519e764e56SPeter Brune *linesearch = snes->linesearch; 58529e764e56SPeter Brune PetscFunctionReturn(0); 58539e764e56SPeter Brune } 5854