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 3563e081fefSLois Curfman McInnes The user can open an alternative visualization context with 357b0a32e0cSBarry Smith PetscViewerASCIIOpen() - output to a specified file. 3589b94acceSBarry Smith 35936851e7fSLois Curfman McInnes Level: beginner 36036851e7fSLois Curfman McInnes 361b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen() 3629b94acceSBarry Smith @*/ 3637087cfbeSBarry Smith PetscErrorCode SNESView(SNES snes,PetscViewer viewer) 3649b94acceSBarry Smith { 365fa9f3622SBarry Smith SNESKSPEW *kctx; 366dfbe8321SBarry Smith PetscErrorCode ierr; 36794b7f48cSBarry Smith KSP ksp; 3687f1410a3SPeter Brune SNESLineSearch linesearch; 36972a02f06SBarry Smith PetscBool iascii,isstring,isbinary,isdraw; 3702d53ad75SBarry Smith DMSNES dmsnes; 371e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 372536b137fSBarry Smith PetscBool issaws; 373bfb97211SBarry Smith #endif 3749b94acceSBarry Smith 3753a40ed3dSBarry Smith PetscFunctionBegin; 3760700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3773050cee2SBarry Smith if (!viewer) { 378ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&viewer);CHKERRQ(ierr); 3793050cee2SBarry Smith } 3800700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 381c9780b6fSBarry Smith PetscCheckSameComm(snes,1,viewer,2); 38274679c65SBarry Smith 383251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 384251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 38555849f57SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 38672a02f06SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 387e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 388536b137fSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 389bfb97211SBarry Smith #endif 39032077d6dSBarry Smith if (iascii) { 391dc0571f2SMatthew G. Knepley SNESNormSchedule normschedule; 3928404b7f3SBarry Smith DM dm; 3938404b7f3SBarry Smith PetscErrorCode (*cJ)(SNES,Vec,Mat,Mat,void*); 3948404b7f3SBarry Smith void *ctx; 395789d8953SBarry Smith const char *pre = ""; 396dc0571f2SMatthew G. Knepley 397dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer);CHKERRQ(ierr); 398fce1e034SJed Brown if (!snes->setupcalled) { 399fce1e034SJed Brown ierr = PetscViewerASCIIPrintf(viewer," SNES has not been set up so information may be incomplete\n");CHKERRQ(ierr); 400fce1e034SJed Brown } 401e7788613SBarry Smith if (snes->ops->view) { 402b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 403e7788613SBarry Smith ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 404b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 4050ef38995SBarry Smith } 40677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr); 40757622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%g, absolute=%g, solution=%g\n",(double)snes->rtol,(double)snes->abstol,(double)snes->stol);CHKERRQ(ierr); 408efd4aadfSBarry Smith if (snes->usesksp) { 40977431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr); 410efd4aadfSBarry Smith } 41177431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr); 412dc0571f2SMatthew G. Knepley ierr = SNESGetNormSchedule(snes, &normschedule);CHKERRQ(ierr); 413dc0571f2SMatthew G. Knepley if (normschedule > 0) {ierr = PetscViewerASCIIPrintf(viewer," norm schedule %s\n",SNESNormSchedules[normschedule]);CHKERRQ(ierr);} 41417fe4bdfSPeter Brune if (snes->gridsequence) { 41517fe4bdfSPeter Brune ierr = PetscViewerASCIIPrintf(viewer," total number of grid sequence refinements=%D\n",snes->gridsequence);CHKERRQ(ierr); 41617fe4bdfSPeter Brune } 4179b94acceSBarry Smith if (snes->ksp_ewconv) { 418fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4199b94acceSBarry Smith if (kctx) { 42077431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr); 42157622a8eSBarry 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); 42257622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," gamma=%g, alpha=%g, alpha2=%g\n",(double)kctx->gamma,(double)kctx->alpha,(double)kctx->alpha2);CHKERRQ(ierr); 4239b94acceSBarry Smith } 4249b94acceSBarry Smith } 425eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 426eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n");CHKERRQ(ierr); 427eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 428eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr); 429eb1f6c34SBarry Smith } 430eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 431eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n");CHKERRQ(ierr); 432eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 43342f4f86dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr); 434eb1f6c34SBarry Smith } 4358404b7f3SBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4368404b7f3SBarry Smith ierr = DMSNESGetJacobian(dm,&cJ,&ctx);CHKERRQ(ierr); 437789d8953SBarry Smith if (snes->mf_operator) { 438789d8953SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is applied matrix-free with differencing\n");CHKERRQ(ierr); 439789d8953SBarry Smith pre = "Preconditioning "; 440789d8953SBarry Smith } 4418404b7f3SBarry Smith if (cJ == SNESComputeJacobianDefault) { 442789d8953SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %sJacobian is built using finite differences one column at a time\n",pre);CHKERRQ(ierr); 4438404b7f3SBarry Smith } else if (cJ == SNESComputeJacobianDefaultColor) { 444789d8953SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %sJacobian is built using finite differences with coloring\n",pre);CHKERRQ(ierr); 445789d8953SBarry Smith /* it slightly breaks data encapsulation for access the DMDA information directly */ 446789d8953SBarry Smith } else if (cJ == SNESComputeJacobian_DMDA) { 447789d8953SBarry Smith MatFDColoring fdcoloring; 448789d8953SBarry Smith ierr = PetscObjectQuery((PetscObject)dm,"DMDASNES_FDCOLORING",(PetscObject*)&fdcoloring);CHKERRQ(ierr); 449789d8953SBarry Smith if (fdcoloring) { 450789d8953SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %sJacobian is built using colored finite differences on a DMDA\n",pre);CHKERRQ(ierr); 451789d8953SBarry Smith } else { 452789d8953SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %sJacobian is built using a DMDA local Jacobian\n",pre);CHKERRQ(ierr); 453789d8953SBarry Smith } 454789d8953SBarry Smith } else if (snes->mf) { 455789d8953SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is applied matrix-free with differencing, no explict Jacobian\n");CHKERRQ(ierr); 4568404b7f3SBarry Smith } 4570f5bd95cSBarry Smith } else if (isstring) { 458317d6ea6SBarry Smith const char *type; 459454a90a3SBarry Smith ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 46036a9e3b9SBarry Smith ierr = PetscViewerStringSPrintf(viewer," SNESType: %-7.7s",type);CHKERRQ(ierr); 46136a9e3b9SBarry Smith if (snes->ops->view) {ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);} 46255849f57SBarry Smith } else if (isbinary) { 46355849f57SBarry Smith PetscInt classid = SNES_FILE_CLASSID; 46455849f57SBarry Smith MPI_Comm comm; 46555849f57SBarry Smith PetscMPIInt rank; 46655849f57SBarry Smith char type[256]; 46755849f57SBarry Smith 46855849f57SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 46955849f57SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 47055849f57SBarry Smith if (!rank) { 471f253e43cSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT);CHKERRQ(ierr); 47289d949e2SBarry Smith ierr = PetscStrncpy(type,((PetscObject)snes)->type_name,sizeof(type));CHKERRQ(ierr); 473f253e43cSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,type,sizeof(type),PETSC_CHAR);CHKERRQ(ierr); 47455849f57SBarry Smith } 47555849f57SBarry Smith if (snes->ops->view) { 47655849f57SBarry Smith ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 47755849f57SBarry Smith } 47872a02f06SBarry Smith } else if (isdraw) { 47972a02f06SBarry Smith PetscDraw draw; 48072a02f06SBarry Smith char str[36]; 48189fd9fafSBarry Smith PetscReal x,y,bottom,h; 48272a02f06SBarry Smith 48372a02f06SBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 48472a02f06SBarry Smith ierr = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr); 485a126751eSBarry Smith ierr = PetscStrncpy(str,"SNES: ",sizeof(str));CHKERRQ(ierr); 486a126751eSBarry Smith ierr = PetscStrlcat(str,((PetscObject)snes)->type_name,sizeof(str));CHKERRQ(ierr); 48751fa3d41SBarry Smith ierr = PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLUE,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr); 48889fd9fafSBarry Smith bottom = y - h; 48972a02f06SBarry Smith ierr = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr); 490c4646bacSPeter Brune if (snes->ops->view) { 491c4646bacSPeter Brune ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 492c4646bacSPeter Brune } 493e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 494536b137fSBarry Smith } else if (issaws) { 495d45a07a7SBarry Smith PetscMPIInt rank; 4962657e9d9SBarry Smith const char *name; 497d45a07a7SBarry Smith 4982657e9d9SBarry Smith ierr = PetscObjectGetName((PetscObject)snes,&name);CHKERRQ(ierr); 499d45a07a7SBarry Smith ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 500d45a07a7SBarry Smith if (!((PetscObject)snes)->amsmem && !rank) { 501d45a07a7SBarry Smith char dir[1024]; 502d45a07a7SBarry Smith 503e04113cfSBarry Smith ierr = PetscObjectViewSAWs((PetscObject)snes,viewer);CHKERRQ(ierr); 5042657e9d9SBarry Smith ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/its",name);CHKERRQ(ierr); 5052657e9d9SBarry Smith PetscStackCallSAWs(SAWs_Register,(dir,&snes->iter,1,SAWs_READ,SAWs_INT)); 506bfb97211SBarry Smith if (!snes->conv_hist) { 507a0931e03SBarry Smith ierr = SNESSetConvergenceHistory(snes,NULL,NULL,PETSC_DECIDE,PETSC_TRUE);CHKERRQ(ierr); 508bfb97211SBarry Smith } 5092657e9d9SBarry Smith ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/conv_hist",name);CHKERRQ(ierr); 5102657e9d9SBarry Smith PetscStackCallSAWs(SAWs_Register,(dir,snes->conv_hist,10,SAWs_READ,SAWs_DOUBLE)); 511f05ece33SBarry Smith } 512bfb97211SBarry Smith #endif 51372a02f06SBarry Smith } 51472a02f06SBarry Smith if (snes->linesearch) { 5157601faf0SJed Brown ierr = SNESGetLineSearch(snes, &linesearch);CHKERRQ(ierr); 51685928a98SStefano Zampini ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 51772a02f06SBarry Smith ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr); 51885928a98SStefano Zampini ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 51919bcc07fSBarry Smith } 520efd4aadfSBarry Smith if (snes->npc && snes->usesnpc) { 52185928a98SStefano Zampini ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 522efd4aadfSBarry Smith ierr = SNESView(snes->npc, viewer);CHKERRQ(ierr); 52385928a98SStefano Zampini ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 5244a0c5b0cSMatthew G Knepley } 5252d53ad75SBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 5262d53ad75SBarry Smith ierr = DMGetDMSNES(snes->dm,&dmsnes);CHKERRQ(ierr); 5272d53ad75SBarry Smith ierr = DMSNESView(dmsnes, viewer);CHKERRQ(ierr); 5282d53ad75SBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 5292c155ee1SBarry Smith if (snes->usesksp) { 5302c155ee1SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 53185928a98SStefano Zampini ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 53294b7f48cSBarry Smith ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 53385928a98SStefano Zampini ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 5342c155ee1SBarry Smith } 53572a02f06SBarry Smith if (isdraw) { 53672a02f06SBarry Smith PetscDraw draw; 53772a02f06SBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 53872a02f06SBarry Smith ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr); 5397f1410a3SPeter Brune } 5403a40ed3dSBarry Smith PetscFunctionReturn(0); 5419b94acceSBarry Smith } 5429b94acceSBarry Smith 54376b2cf59SMatthew Knepley /* 54476b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 54576b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 54676b2cf59SMatthew Knepley */ 54776b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 548a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 5496849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 55076b2cf59SMatthew Knepley 551ac226902SBarry Smith /*@C 55276b2cf59SMatthew Knepley SNESAddOptionsChecker - Adds an additional function to check for SNES options. 55376b2cf59SMatthew Knepley 55476b2cf59SMatthew Knepley Not Collective 55576b2cf59SMatthew Knepley 55676b2cf59SMatthew Knepley Input Parameter: 55776b2cf59SMatthew Knepley . snescheck - function that checks for options 55876b2cf59SMatthew Knepley 55976b2cf59SMatthew Knepley Level: developer 56076b2cf59SMatthew Knepley 56176b2cf59SMatthew Knepley .seealso: SNESSetFromOptions() 56276b2cf59SMatthew Knepley @*/ 5637087cfbeSBarry Smith PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 56476b2cf59SMatthew Knepley { 56576b2cf59SMatthew Knepley PetscFunctionBegin; 566f23aa3ddSBarry Smith if (numberofsetfromoptions >= MAXSETFROMOPTIONS) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 56776b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 56876b2cf59SMatthew Knepley PetscFunctionReturn(0); 56976b2cf59SMatthew Knepley } 57076b2cf59SMatthew Knepley 57125acbd8eSLisandro Dalcin PETSC_INTERN PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 572aa3661deSLisandro Dalcin 573ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 574aa3661deSLisandro Dalcin { 575aa3661deSLisandro Dalcin Mat J; 576aa3661deSLisandro Dalcin PetscErrorCode ierr; 577895c21f2SBarry Smith MatNullSpace nullsp; 578aa3661deSLisandro Dalcin 579aa3661deSLisandro Dalcin PetscFunctionBegin; 5800700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 581aa3661deSLisandro Dalcin 58298613b67SLisandro Dalcin if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 58398613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 5842a7a6963SBarry Smith ierr = MatCreateVecs(A ? A : B, NULL,&snes->vec_func);CHKERRQ(ierr); 58598613b67SLisandro Dalcin } 58698613b67SLisandro Dalcin 587aa3661deSLisandro Dalcin if (version == 1) { 588aa3661deSLisandro Dalcin ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 58998613b67SLisandro Dalcin ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 5909c6ac3b3SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 591aa3661deSLisandro Dalcin } else if (version == 2) { 592e32f2f54SBarry Smith if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 593570b7f6dSBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FP16) 594aa3661deSLisandro Dalcin ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr); 595aa3661deSLisandro Dalcin #else 596*2479783cSJose E. Roman SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator routines (version 2)"); 597aa3661deSLisandro Dalcin #endif 598*2479783cSJose E. Roman } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator routines, only version 1 and 2"); 599aa3661deSLisandro Dalcin 600895c21f2SBarry Smith /* attach any user provided null space that was on Amat to the newly created matrix free matrix */ 601895c21f2SBarry Smith if (snes->jacobian) { 602895c21f2SBarry Smith ierr = MatGetNullSpace(snes->jacobian,&nullsp);CHKERRQ(ierr); 603895c21f2SBarry Smith if (nullsp) { 604895c21f2SBarry Smith ierr = MatSetNullSpace(J,nullsp);CHKERRQ(ierr); 605895c21f2SBarry Smith } 606895c21f2SBarry Smith } 607895c21f2SBarry Smith 608aa3661deSLisandro Dalcin ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr); 609d3462f78SMatthew Knepley if (hasOperator) { 6103232da50SPeter Brune 611aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 612aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 6139e5d0892SLisandro Dalcin ierr = SNESSetJacobian(snes,J,NULL,NULL,NULL);CHKERRQ(ierr); 614aa3661deSLisandro Dalcin } else { 615aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 6163232da50SPeter Brune provided preconditioner Jacobian with the default matrix free version. */ 617efd4aadfSBarry Smith if ((snes->npcside== PC_LEFT) && snes->npc) { 6189e5d0892SLisandro Dalcin if (!snes->jacobian){ierr = SNESSetJacobian(snes,J,NULL,NULL,NULL);CHKERRQ(ierr);} 619172a4300SPeter Brune } else { 620789d8953SBarry Smith KSP ksp; 621789d8953SBarry Smith PC pc; 622789d8953SBarry Smith PetscBool match; 623789d8953SBarry Smith 6249e5d0892SLisandro Dalcin ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,NULL);CHKERRQ(ierr); 625aa3661deSLisandro Dalcin /* Force no preconditioner */ 626aa3661deSLisandro Dalcin ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 627aa3661deSLisandro Dalcin ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 628251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr); 629aa3661deSLisandro Dalcin if (!match) { 630aa3661deSLisandro Dalcin ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 631aa3661deSLisandro Dalcin ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 632aa3661deSLisandro Dalcin } 633aa3661deSLisandro Dalcin } 634789d8953SBarry Smith } 6356bf464f9SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 636aa3661deSLisandro Dalcin PetscFunctionReturn(0); 637aa3661deSLisandro Dalcin } 638aa3661deSLisandro Dalcin 639dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx) 640dfe15315SJed Brown { 641dfe15315SJed Brown SNES snes = (SNES)ctx; 642dfe15315SJed Brown PetscErrorCode ierr; 6430298fd71SBarry Smith Vec Xfine,Xfine_named = NULL,Xcoarse; 644dfe15315SJed Brown 645dfe15315SJed Brown PetscFunctionBegin; 64616ebb321SJed Brown if (PetscLogPrintInfo) { 64716ebb321SJed Brown PetscInt finelevel,coarselevel,fineclevel,coarseclevel; 64816ebb321SJed Brown ierr = DMGetRefineLevel(dmfine,&finelevel);CHKERRQ(ierr); 64916ebb321SJed Brown ierr = DMGetCoarsenLevel(dmfine,&fineclevel);CHKERRQ(ierr); 65016ebb321SJed Brown ierr = DMGetRefineLevel(dmcoarse,&coarselevel);CHKERRQ(ierr); 65116ebb321SJed Brown ierr = DMGetCoarsenLevel(dmcoarse,&coarseclevel);CHKERRQ(ierr); 65216ebb321SJed Brown ierr = PetscInfo4(dmfine,"Restricting SNES solution vector from level %D-%D to level %D-%D\n",finelevel,fineclevel,coarselevel,coarseclevel);CHKERRQ(ierr); 65316ebb321SJed Brown } 654dfe15315SJed Brown if (dmfine == snes->dm) Xfine = snes->vec_sol; 655dfe15315SJed Brown else { 656dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr); 657dfe15315SJed Brown Xfine = Xfine_named; 658dfe15315SJed Brown } 659dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 660907f5c5aSLawrence Mitchell if (Inject) { 661907f5c5aSLawrence Mitchell ierr = MatRestrict(Inject,Xfine,Xcoarse);CHKERRQ(ierr); 662907f5c5aSLawrence Mitchell } else { 663dfe15315SJed Brown ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr); 664dfe15315SJed Brown ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr); 665907f5c5aSLawrence Mitchell } 666dfe15315SJed Brown ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 667dfe15315SJed Brown if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);} 668dfe15315SJed Brown PetscFunctionReturn(0); 669dfe15315SJed Brown } 670dfe15315SJed Brown 67116ebb321SJed Brown static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx) 67216ebb321SJed Brown { 67316ebb321SJed Brown PetscErrorCode ierr; 67416ebb321SJed Brown 67516ebb321SJed Brown PetscFunctionBegin; 67616ebb321SJed Brown ierr = DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx);CHKERRQ(ierr); 67716ebb321SJed Brown PetscFunctionReturn(0); 67816ebb321SJed Brown } 67916ebb321SJed Brown 680a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can 681a6950cb2SJed Brown * safely call SNESGetDM() in their residual evaluation routine. */ 68223ee1639SBarry Smith static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,void *ctx) 683caa4e7f2SJed Brown { 684caa4e7f2SJed Brown SNES snes = (SNES)ctx; 685caa4e7f2SJed Brown PetscErrorCode ierr; 6860298fd71SBarry Smith Vec X,Xnamed = NULL; 687dfe15315SJed Brown DM dmsave; 6884e269d77SPeter Brune void *ctxsave; 68925ce1634SJed Brown PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*) = NULL; 690caa4e7f2SJed Brown 691caa4e7f2SJed Brown PetscFunctionBegin; 692dfe15315SJed Brown dmsave = snes->dm; 693dfe15315SJed Brown ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr); 694dfe15315SJed Brown if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */ 695dfe15315SJed Brown else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ 696dfe15315SJed Brown ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 697dfe15315SJed Brown X = Xnamed; 6980298fd71SBarry Smith ierr = SNESGetJacobian(snes,NULL,NULL,&jac,&ctxsave);CHKERRQ(ierr); 6994e269d77SPeter Brune /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */ 7008d359177SBarry Smith if (jac == SNESComputeJacobianDefaultColor) { 7019e5d0892SLisandro Dalcin ierr = SNESSetJacobian(snes,NULL,NULL,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr); 702dfe15315SJed Brown } 7034e269d77SPeter Brune } 7044dde8bb0SMatthew G. Knepley /* Make sure KSP DM has the Jacobian computation routine */ 7054dde8bb0SMatthew G. Knepley { 7064dde8bb0SMatthew G. Knepley DMSNES sdm; 7074e269d77SPeter Brune 7084dde8bb0SMatthew G. Knepley ierr = DMGetDMSNES(snes->dm, &sdm);CHKERRQ(ierr); 7094dde8bb0SMatthew G. Knepley if (!sdm->ops->computejacobian) { 7104dde8bb0SMatthew G. Knepley ierr = DMCopyDMSNES(dmsave, snes->dm);CHKERRQ(ierr); 7114dde8bb0SMatthew G. Knepley } 7124dde8bb0SMatthew G. Knepley } 7132b93b426SMatthew G. Knepley /* Compute the operators */ 714d1e9a80fSBarry Smith ierr = SNESComputeJacobian(snes,X,A,B);CHKERRQ(ierr); 7152b93b426SMatthew G. Knepley /* Put the previous context back */ 7168d359177SBarry Smith if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) { 7170298fd71SBarry Smith ierr = SNESSetJacobian(snes,NULL,NULL,jac,ctxsave);CHKERRQ(ierr); 7184e269d77SPeter Brune } 7194e269d77SPeter Brune 7202b93b426SMatthew G. Knepley if (Xnamed) {ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);} 721dfe15315SJed Brown snes->dm = dmsave; 722caa4e7f2SJed Brown PetscFunctionReturn(0); 723caa4e7f2SJed Brown } 724caa4e7f2SJed Brown 7256cab3a1bSJed Brown /*@ 7266cab3a1bSJed Brown SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX() 7276cab3a1bSJed Brown 7286cab3a1bSJed Brown Collective 7296cab3a1bSJed Brown 7306cab3a1bSJed Brown Input Arguments: 7316cab3a1bSJed Brown . snes - snes to configure 7326cab3a1bSJed Brown 7336cab3a1bSJed Brown Level: developer 7346cab3a1bSJed Brown 7356cab3a1bSJed Brown .seealso: SNESSetUp() 7366cab3a1bSJed Brown @*/ 7376cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes) 7386cab3a1bSJed Brown { 7396cab3a1bSJed Brown PetscErrorCode ierr; 7406cab3a1bSJed Brown DM dm; 741942e3340SBarry Smith DMSNES sdm; 7426cab3a1bSJed Brown 7436cab3a1bSJed Brown PetscFunctionBegin; 7446cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 745942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 74658b371f3SBarry Smith if (!snes->jacobian && snes->mf) { 7476cab3a1bSJed Brown Mat J; 7486cab3a1bSJed Brown void *functx; 7496cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 7506cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 7516cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 7520298fd71SBarry Smith ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr); 7539e5d0892SLisandro Dalcin ierr = SNESSetJacobian(snes,J,J,NULL,NULL);CHKERRQ(ierr); 7546cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 755caa4e7f2SJed Brown } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 7566cab3a1bSJed Brown Mat J,B; 7576cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 7586cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 7596cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 760b412c318SBarry Smith ierr = DMCreateMatrix(snes->dm,&B);CHKERRQ(ierr); 76106f20277SJed Brown /* sdm->computejacobian was already set to reach here */ 7620298fd71SBarry Smith ierr = SNESSetJacobian(snes,J,B,NULL,NULL);CHKERRQ(ierr); 7636cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 7646cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 765caa4e7f2SJed Brown } else if (!snes->jacobian_pre) { 7668cda7954SMatthew G. Knepley PetscErrorCode (*nspconstr)(DM, PetscInt, PetscInt, MatNullSpace *); 7671ba9b98eSMatthew G. Knepley PetscDS prob; 7686cab3a1bSJed Brown Mat J, B; 7694f3e65b0SMatthew G. Knepley MatNullSpace nullspace = NULL; 7701ba9b98eSMatthew G. Knepley PetscBool hasPrec = PETSC_FALSE; 7714f3e65b0SMatthew G. Knepley PetscInt Nf; 7721ba9b98eSMatthew G. Knepley 7736cab3a1bSJed Brown J = snes->jacobian; 7741ba9b98eSMatthew G. Knepley ierr = DMGetDS(dm, &prob);CHKERRQ(ierr); 7751ba9b98eSMatthew G. Knepley if (prob) {ierr = PetscDSHasJacobianPreconditioner(prob, &hasPrec);CHKERRQ(ierr);} 776ec9a985fSMatthew G. Knepley if (J) {ierr = PetscObjectReference((PetscObject) J);CHKERRQ(ierr);} 777ec9a985fSMatthew G. Knepley else if (hasPrec) {ierr = DMCreateMatrix(snes->dm, &J);CHKERRQ(ierr);} 778b412c318SBarry Smith ierr = DMCreateMatrix(snes->dm, &B);CHKERRQ(ierr); 7794f3e65b0SMatthew G. Knepley ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 7804f3e65b0SMatthew G. Knepley ierr = DMGetNullSpaceConstructor(snes->dm, Nf, &nspconstr);CHKERRQ(ierr); 7818cda7954SMatthew G. Knepley if (nspconstr) (*nspconstr)(snes->dm, Nf, Nf, &nullspace); 7824f3e65b0SMatthew G. Knepley ierr = MatSetNullSpace(B, nullspace);CHKERRQ(ierr); 7834f3e65b0SMatthew G. Knepley ierr = MatNullSpaceDestroy(&nullspace);CHKERRQ(ierr); 7840298fd71SBarry Smith ierr = SNESSetJacobian(snes, J ? J : B, B, NULL, NULL);CHKERRQ(ierr); 7851ba9b98eSMatthew G. Knepley ierr = MatDestroy(&J);CHKERRQ(ierr); 7866cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 7876cab3a1bSJed Brown } 788caa4e7f2SJed Brown { 789caa4e7f2SJed Brown KSP ksp; 790caa4e7f2SJed Brown ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 791caa4e7f2SJed Brown ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr); 79216ebb321SJed Brown ierr = DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 793caa4e7f2SJed Brown } 7946cab3a1bSJed Brown PetscFunctionReturn(0); 7956cab3a1bSJed Brown } 7966cab3a1bSJed Brown 797fde5950dSBarry Smith /*@C 798fde5950dSBarry Smith SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 799fde5950dSBarry Smith 800fde5950dSBarry Smith Collective on SNES 801fde5950dSBarry Smith 802fde5950dSBarry Smith Input Parameters: 803fde5950dSBarry Smith + snes - SNES object you wish to monitor 804fde5950dSBarry Smith . name - the monitor type one is seeking 805fde5950dSBarry Smith . help - message indicating what monitoring is done 806fde5950dSBarry Smith . manual - manual page for the monitor 807fde5950dSBarry Smith . monitor - the monitor function 808fde5950dSBarry 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 809fde5950dSBarry Smith 810fde5950dSBarry Smith Level: developer 811fde5950dSBarry Smith 812fde5950dSBarry Smith .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 813fde5950dSBarry Smith PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 814fde5950dSBarry Smith PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 815fde5950dSBarry Smith PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 816fde5950dSBarry Smith PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 817fde5950dSBarry Smith PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 818fde5950dSBarry Smith PetscOptionsFList(), PetscOptionsEList() 819fde5950dSBarry Smith @*/ 820d43b4f6eSBarry Smith PetscErrorCode SNESMonitorSetFromOptions(SNES snes,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNES,PetscViewerAndFormat*)) 821fde5950dSBarry Smith { 822fde5950dSBarry Smith PetscErrorCode ierr; 823fde5950dSBarry Smith PetscViewer viewer; 824fde5950dSBarry Smith PetscViewerFormat format; 825fde5950dSBarry Smith PetscBool flg; 826fde5950dSBarry Smith 827fde5950dSBarry Smith PetscFunctionBegin; 82816413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr); 829fde5950dSBarry Smith if (flg) { 830d43b4f6eSBarry Smith PetscViewerAndFormat *vf; 831d43b4f6eSBarry Smith ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr); 832d43b4f6eSBarry Smith ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr); 833fde5950dSBarry Smith if (monitorsetup) { 834d43b4f6eSBarry Smith ierr = (*monitorsetup)(snes,vf);CHKERRQ(ierr); 835fde5950dSBarry Smith } 836d43b4f6eSBarry Smith ierr = SNESMonitorSet(snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);CHKERRQ(ierr); 837fde5950dSBarry Smith } 838fde5950dSBarry Smith PetscFunctionReturn(0); 839fde5950dSBarry Smith } 840fde5950dSBarry Smith 8419b94acceSBarry Smith /*@ 84294b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 8439b94acceSBarry Smith 844c7afd0dbSLois Curfman McInnes Collective on SNES 845c7afd0dbSLois Curfman McInnes 8469b94acceSBarry Smith Input Parameter: 8479b94acceSBarry Smith . snes - the SNES context 8489b94acceSBarry Smith 84936851e7fSLois Curfman McInnes Options Database Keys: 850722329fbSBarry Smith + -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, SNESType for complete list 85182738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 85282738288SBarry Smith of the change in the solution between steps 85370441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 854b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 855e4d06f11SPatrick Farrell . -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence 856be5caee7SBarry Smith . -snes_force_iteration <force> - force SNESSolve() to take at least one iteration 857b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 858b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 8594839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 860ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 861a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 8623d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - retains the -snes_lag_preconditioner information across multiple SNESSolve() 863e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 8643d5a8a6aSBarry Smith . -snes_lag_jacobian_persists <true,false> - retains the -snes_lag_jacobian information across multiple SNESSolve() 865b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 8662492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 86782738288SBarry Smith solver; hence iterations will continue until max_it 8681fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 86982738288SBarry Smith of convergence test 870fde5950dSBarry Smith . -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout 871fde5950dSBarry Smith . -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration 872fde5950dSBarry Smith . -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration 873fde5950dSBarry Smith . -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration 8744619e776SBarry Smith . -snes_monitor_lg_residualnorm - plots residual norm at each iteration 875459f5d12SBarry Smith . -snes_monitor_lg_range - plots residual norm at each iteration 876e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 877e2e60de9SPeter Brune . -snes_fd_color - use finite differences with coloring to compute Jacobian 8785968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 879b5badacbSBarry Smith . -snes_converged_reason - print the reason for convergence/divergence after each solve 880b5badacbSBarry Smith - -npc_snes_type <type> - the SNES type to use as a nonlinear preconditioner 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; 90885385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 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 96385385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"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; 96885385478SLisandro Dalcin } 96985385478SLisandro Dalcin } 97085385478SLisandro Dalcin 971365a6726SPeter Brune ierr = PetscOptionsEList("-snes_norm_schedule","SNES Norm schedule","SNESSetNormSchedule",SNESNormSchedules,5,"function",&indx,&flg);CHKERRQ(ierr); 972365a6726SPeter Brune if (flg) { ierr = SNESSetNormSchedule(snes,(SNESNormSchedule)indx);CHKERRQ(ierr); } 973fdacfa88SPeter Brune 97447073ea2SPeter Brune ierr = PetscOptionsEList("-snes_function_type","SNES Norm schedule","SNESSetFunctionType",SNESFunctionTypes,2,"unpreconditioned",&indx,&flg);CHKERRQ(ierr); 97547073ea2SPeter Brune if (flg) { ierr = SNESSetFunctionType(snes,(SNESFunctionType)indx);CHKERRQ(ierr); } 976186905e3SBarry Smith 97785385478SLisandro Dalcin kctx = (SNESKSPEW*)snes->kspconvctx; 97885385478SLisandro Dalcin 9790298fd71SBarry Smith ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,NULL);CHKERRQ(ierr); 980186905e3SBarry Smith 98194ae4db5SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,NULL);CHKERRQ(ierr); 98294ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,NULL);CHKERRQ(ierr); 98394ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,NULL);CHKERRQ(ierr); 98494ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,NULL);CHKERRQ(ierr); 98594ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,NULL);CHKERRQ(ierr); 98694ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,NULL);CHKERRQ(ierr); 98794ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,NULL);CHKERRQ(ierr); 988186905e3SBarry Smith 98990d69ab7SBarry Smith flg = PETSC_FALSE; 9908afaa268SBarry Smith ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,&set);CHKERRQ(ierr); 9918afaa268SBarry Smith if (set && flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 992eabae89aSBarry Smith 993fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor","Monitor norm of function","SNESMonitorDefault",SNESMonitorDefault,NULL);CHKERRQ(ierr); 994fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_short","Monitor norm of function with fewer digits","SNESMonitorDefaultShort",SNESMonitorDefaultShort,NULL);CHKERRQ(ierr); 995fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_range","Monitor range of elements of function","SNESMonitorRange",SNESMonitorRange,NULL);CHKERRQ(ierr); 996eabae89aSBarry Smith 997fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_ratio","Monitor ratios of the norm of function for consecutive steps","SNESMonitorRatio",SNESMonitorRatio,SNESMonitorRatioSetUp);CHKERRQ(ierr); 998fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_field","Monitor norm of function (split into fields)","SNESMonitorDefaultField",SNESMonitorDefaultField,NULL);CHKERRQ(ierr); 999fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_solution","View solution at each iteration","SNESMonitorSolution",SNESMonitorSolution,NULL);CHKERRQ(ierr); 1000fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_solution_update","View correction at each iteration","SNESMonitorSolutionUpdate",SNESMonitorSolutionUpdate,NULL);CHKERRQ(ierr); 1001fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_residual","View residual at each iteration","SNESMonitorResidual",SNESMonitorResidual,NULL);CHKERRQ(ierr); 1002fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",SNESMonitorJacUpdateSpectrum,NULL);CHKERRQ(ierr); 1003fde5950dSBarry Smith ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_fields","Monitor norm of function per field","SNESMonitorSet",SNESMonitorFields,NULL);CHKERRQ(ierr); 10042db13446SMatthew G. Knepley 1005589a23caSBarry Smith ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",NULL,monfilename,sizeof(monfilename),&flg);CHKERRQ(ierr); 10065180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 10075180491cSLisandro Dalcin 100890d69ab7SBarry Smith flg = PETSC_FALSE; 10090298fd71SBarry Smith ierr = PetscOptionsBool("-snes_monitor_lg_residualnorm","Plot function norm at each iteration","SNESMonitorLGResidualNorm",flg,&flg,NULL);CHKERRQ(ierr); 1010459f5d12SBarry Smith if (flg) { 1011d96771aaSLisandro Dalcin PetscDrawLG ctx; 1012459f5d12SBarry Smith 10136ba87a44SLisandro Dalcin ierr = SNESMonitorLGCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr); 1014d96771aaSLisandro Dalcin ierr = SNESMonitorSet(snes,SNESMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);CHKERRQ(ierr); 1015459f5d12SBarry Smith } 101690d69ab7SBarry Smith flg = PETSC_FALSE; 10170298fd71SBarry Smith ierr = PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,NULL);CHKERRQ(ierr); 1018459f5d12SBarry Smith if (flg) { 1019459f5d12SBarry Smith PetscViewer ctx; 1020e24b481bSBarry Smith 10216ba87a44SLisandro Dalcin ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr); 1022459f5d12SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 1023459f5d12SBarry Smith } 10242e7541e6SPeter Brune 102590d69ab7SBarry Smith flg = PETSC_FALSE; 10268d359177SBarry Smith ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESComputeJacobianDefault",flg,&flg,NULL);CHKERRQ(ierr); 10274b27c08aSLois Curfman McInnes if (flg) { 10286cab3a1bSJed Brown void *functx; 1029b1f624c7SBarry Smith DM dm; 1030b1f624c7SBarry Smith DMSNES sdm; 1031b1f624c7SBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1032b1f624c7SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 1033b1f624c7SBarry Smith sdm->jacobianctx = NULL; 10340298fd71SBarry Smith ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr); 10358d359177SBarry Smith ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefault,functx);CHKERRQ(ierr); 1036ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 10379b94acceSBarry Smith } 1038639f9d9dSBarry Smith 103944848bc4SPeter Brune flg = PETSC_FALSE; 10408d359177SBarry Smith ierr = PetscOptionsBool("-snes_fd_function","Use finite differences (slow) to compute function from user objective","SNESObjectiveComputeFunctionDefaultFD",flg,&flg,NULL);CHKERRQ(ierr); 104197584545SPeter Brune if (flg) { 10428d359177SBarry Smith ierr = SNESSetFunction(snes,NULL,SNESObjectiveComputeFunctionDefaultFD,NULL);CHKERRQ(ierr); 104397584545SPeter Brune } 104497584545SPeter Brune 104597584545SPeter Brune flg = PETSC_FALSE; 10468d359177SBarry Smith ierr = PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESComputeJacobianDefaultColor",flg,&flg,NULL);CHKERRQ(ierr); 104744848bc4SPeter Brune if (flg) { 1048c52e227fSPeter Brune DM dm; 1049c52e227fSPeter Brune DMSNES sdm; 1050c52e227fSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1051aace71b7SPeter Brune ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 1052aace71b7SPeter Brune sdm->jacobianctx = NULL; 10539e5d0892SLisandro Dalcin ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr); 105444848bc4SPeter Brune ierr = PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr); 105544848bc4SPeter Brune } 105644848bc4SPeter Brune 1057aa3661deSLisandro Dalcin flg = PETSC_FALSE; 1058f871313dSBarry 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); 1059d8f46077SPeter Brune if (flg && snes->mf_operator) { 1060a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 1061d8f46077SPeter Brune snes->mf = PETSC_TRUE; 1062a8248277SBarry Smith } 1063aa3661deSLisandro Dalcin flg = PETSC_FALSE; 1064f871313dSBarry Smith ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf,&flg);CHKERRQ(ierr); 1065d8f46077SPeter Brune if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE; 10669e5d0892SLisandro Dalcin ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,NULL);CHKERRQ(ierr); 1067d28543b3SPeter Brune 1068c40d0f55SPeter Brune flg = PETSC_FALSE; 1069be95d8f1SBarry Smith ierr = SNESGetNPCSide(snes,&pcside);CHKERRQ(ierr); 1070be95d8f1SBarry Smith ierr = PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetNPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);CHKERRQ(ierr); 1071be95d8f1SBarry Smith if (flg) {ierr = SNESSetNPCSide(snes,pcside);CHKERRQ(ierr);} 1072c40d0f55SPeter Brune 1073e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 10748a70d858SHong Zhang /* 10758a70d858SHong Zhang Publish convergence information using SAWs 10768a70d858SHong Zhang */ 10778a70d858SHong Zhang flg = PETSC_FALSE; 10788a70d858SHong Zhang ierr = PetscOptionsBool("-snes_monitor_saws","Publish SNES progress using SAWs","SNESMonitorSet",flg,&flg,NULL);CHKERRQ(ierr); 10798a70d858SHong Zhang if (flg) { 10808a70d858SHong Zhang void *ctx; 10818a70d858SHong Zhang ierr = SNESMonitorSAWsCreate(snes,&ctx);CHKERRQ(ierr); 10828a70d858SHong Zhang ierr = SNESMonitorSet(snes,SNESMonitorSAWs,ctx,SNESMonitorSAWsDestroy);CHKERRQ(ierr); 10838a70d858SHong Zhang } 10848a70d858SHong Zhang #endif 10858a70d858SHong Zhang #if defined(PETSC_HAVE_SAWS) 1086b90c6cbeSBarry Smith { 1087b90c6cbeSBarry Smith PetscBool set; 1088b90c6cbeSBarry Smith flg = PETSC_FALSE; 10898a70d858SHong Zhang ierr = PetscOptionsBool("-snes_saws_block","Block for SAWs at end of SNESSolve","PetscObjectSAWsBlock",((PetscObject)snes)->amspublishblock,&flg,&set);CHKERRQ(ierr); 1090b90c6cbeSBarry Smith if (set) { 1091e04113cfSBarry Smith ierr = PetscObjectSAWsSetBlock((PetscObject)snes,flg);CHKERRQ(ierr); 1092b90c6cbeSBarry Smith } 1093b90c6cbeSBarry Smith } 1094b90c6cbeSBarry Smith #endif 1095b90c6cbeSBarry Smith 109676b2cf59SMatthew Knepley for (i = 0; i < numberofsetfromoptions; i++) { 109776b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 109876b2cf59SMatthew Knepley } 109976b2cf59SMatthew Knepley 1100e7788613SBarry Smith if (snes->ops->setfromoptions) { 1101e55864a3SBarry Smith ierr = (*snes->ops->setfromoptions)(PetscOptionsObject,snes);CHKERRQ(ierr); 1102639f9d9dSBarry Smith } 11035d973c19SBarry Smith 11045d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 11050633abcbSJed Brown ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)snes);CHKERRQ(ierr); 1106b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 11074bbc92c1SBarry Smith 1108d8d34be6SBarry Smith if (snes->linesearch) { 11097601faf0SJed Brown ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 1110f1c6b773SPeter Brune ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr); 1111d8d34be6SBarry Smith } 11129e764e56SPeter Brune 11136aa5e7e9SBarry Smith if (snes->usesksp) { 11146991f827SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 11156991f827SBarry Smith ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre);CHKERRQ(ierr); 11166991f827SBarry Smith ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 11176aa5e7e9SBarry Smith } 11186991f827SBarry Smith 1119b5badacbSBarry Smith /* if user has set the SNES NPC type via options database, create it. */ 112051e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 1121c5929fdfSBarry Smith ierr = PetscOptionsHasName(((PetscObject)snes)->options,optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 1122efd4aadfSBarry Smith if (pcset && (!snes->npc)) { 1123efd4aadfSBarry Smith ierr = SNESGetNPC(snes, &snes->npc);CHKERRQ(ierr); 112451e86f29SPeter Brune } 1125b5badacbSBarry Smith if (snes->npc) { 1126b5badacbSBarry Smith ierr = SNESSetFromOptions(snes->npc);CHKERRQ(ierr); 1127b5badacbSBarry Smith } 1128b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled++; 1129b3cd9a81SMatthew G. Knepley PetscFunctionReturn(0); 1130b3cd9a81SMatthew G. Knepley } 1131b3cd9a81SMatthew G. Knepley 1132b3cd9a81SMatthew G. Knepley /*@ 1133b3cd9a81SMatthew G. Knepley SNESResetFromOptions - Sets various SNES and KSP parameters from user options ONLY if the SNES was previously set from options 1134b3cd9a81SMatthew G. Knepley 1135b3cd9a81SMatthew G. Knepley Collective on SNES 1136b3cd9a81SMatthew G. Knepley 1137b3cd9a81SMatthew G. Knepley Input Parameter: 1138b3cd9a81SMatthew G. Knepley . snes - the SNES context 1139b3cd9a81SMatthew G. Knepley 1140b3cd9a81SMatthew G. Knepley Level: beginner 1141b3cd9a81SMatthew G. Knepley 1142b3cd9a81SMatthew G. Knepley .seealso: SNESSetFromOptions(), SNESSetOptionsPrefix() 1143b3cd9a81SMatthew G. Knepley @*/ 1144b3cd9a81SMatthew G. Knepley PetscErrorCode SNESResetFromOptions(SNES snes) 1145b3cd9a81SMatthew G. Knepley { 1146b3cd9a81SMatthew G. Knepley PetscErrorCode ierr; 1147b3cd9a81SMatthew G. Knepley 1148b3cd9a81SMatthew G. Knepley PetscFunctionBegin; 1149b3cd9a81SMatthew G. Knepley if (snes->setfromoptionscalled) {ierr = SNESSetFromOptions(snes);CHKERRQ(ierr);} 11503a40ed3dSBarry Smith PetscFunctionReturn(0); 11519b94acceSBarry Smith } 11529b94acceSBarry Smith 1153bb9467b5SJed Brown /*@C 1154d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 1155d25893d9SBarry Smith the nonlinear solvers. 1156d25893d9SBarry Smith 1157d25893d9SBarry Smith Logically Collective on SNES 1158d25893d9SBarry Smith 1159d25893d9SBarry Smith Input Parameters: 1160d25893d9SBarry Smith + snes - the SNES context 1161d25893d9SBarry Smith . compute - function to compute the context 1162d25893d9SBarry Smith - destroy - function to destroy the context 1163d25893d9SBarry Smith 1164d25893d9SBarry Smith Level: intermediate 1165d25893d9SBarry Smith 1166bb9467b5SJed Brown Notes: 1167bb9467b5SJed Brown This function is currently not available from Fortran. 1168bb9467b5SJed Brown 1169d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 1170d25893d9SBarry Smith @*/ 1171d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 1172d25893d9SBarry Smith { 1173d25893d9SBarry Smith PetscFunctionBegin; 1174d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1175d25893d9SBarry Smith snes->ops->usercompute = compute; 1176d25893d9SBarry Smith snes->ops->userdestroy = destroy; 1177d25893d9SBarry Smith PetscFunctionReturn(0); 1178d25893d9SBarry Smith } 1179a847f771SSatish Balay 1180b07ff414SBarry Smith /*@ 11819b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 11829b94acceSBarry Smith the nonlinear solvers. 11839b94acceSBarry Smith 11843f9fe445SBarry Smith Logically Collective on SNES 1185fee21e36SBarry Smith 1186c7afd0dbSLois Curfman McInnes Input Parameters: 1187c7afd0dbSLois Curfman McInnes + snes - the SNES context 1188c7afd0dbSLois Curfman McInnes - usrP - optional user context 1189c7afd0dbSLois Curfman McInnes 119036851e7fSLois Curfman McInnes Level: intermediate 119136851e7fSLois Curfman McInnes 119295452b02SPatrick Sanan Fortran Notes: 119395452b02SPatrick Sanan To use this from Fortran you must write a Fortran interface definition for this 1194daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1195daf670e6SBarry Smith 1196ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext() 11979b94acceSBarry Smith @*/ 11987087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 11999b94acceSBarry Smith { 12001b2093e4SBarry Smith PetscErrorCode ierr; 1201b07ff414SBarry Smith KSP ksp; 12021b2093e4SBarry Smith 12033a40ed3dSBarry Smith PetscFunctionBegin; 12040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1205b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 1206b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 12079b94acceSBarry Smith snes->user = usrP; 12083a40ed3dSBarry Smith PetscFunctionReturn(0); 12099b94acceSBarry Smith } 121074679c65SBarry Smith 1211b07ff414SBarry Smith /*@ 12129b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 12139b94acceSBarry Smith nonlinear solvers. 12149b94acceSBarry Smith 1215c7afd0dbSLois Curfman McInnes Not Collective 1216c7afd0dbSLois Curfman McInnes 12179b94acceSBarry Smith Input Parameter: 12189b94acceSBarry Smith . snes - SNES context 12199b94acceSBarry Smith 12209b94acceSBarry Smith Output Parameter: 12219b94acceSBarry Smith . usrP - user context 12229b94acceSBarry Smith 122395452b02SPatrick Sanan Fortran Notes: 122495452b02SPatrick Sanan To use this from Fortran you must write a Fortran interface definition for this 1225daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1226daf670e6SBarry Smith 122736851e7fSLois Curfman McInnes Level: intermediate 122836851e7fSLois Curfman McInnes 12299b94acceSBarry Smith .seealso: SNESSetApplicationContext() 12309b94acceSBarry Smith @*/ 1231e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 12329b94acceSBarry Smith { 12333a40ed3dSBarry Smith PetscFunctionBegin; 12340700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1235e71120c6SJed Brown *(void**)usrP = snes->user; 12363a40ed3dSBarry Smith PetscFunctionReturn(0); 12379b94acceSBarry Smith } 123874679c65SBarry Smith 12399b94acceSBarry Smith /*@ 1240ec5066bdSBarry Smith SNESSetUseMatrixFree - indicates that SNES should use matrix free finite difference matrix vector products internally to apply the Jacobian. 12413565c898SBarry Smith 12423565c898SBarry Smith Collective on SNES 12433565c898SBarry Smith 12443565c898SBarry Smith Input Parameters: 12453565c898SBarry Smith + snes - SNES context 12464ddffce6SLisandro Dalcin . mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used 12474ddffce6SLisandro 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 12483565c898SBarry Smith 12493565c898SBarry Smith Options Database: 12503565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator 1251ec5066bdSBarry Smith . -snes_mf_operator - use matrix free only for the mat operator 1252ec5066bdSBarry Smith . -snes_fd_color - compute the Jacobian via coloring and finite differences. 1253ec5066bdSBarry Smith - -snes_fd - compute the Jacobian via finite differences (slow) 12543565c898SBarry Smith 12553565c898SBarry Smith Level: intermediate 12563565c898SBarry Smith 1257ec5066bdSBarry Smith Notes: 1258ec5066bdSBarry Smith SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free, and computing explictly with 1259ec5066bdSBarry Smith finite differences and coloring using MatFDColoring. It is also possible to use automatic differentiation and the MatFDColoring object. 1260ec5066bdSBarry Smith 1261ec5066bdSBarry Smith .seealso: SNESGetUseMatrixFree(), MatCreateSNESMF(), SNESComputeJacobianDefaultColor() 12623565c898SBarry Smith @*/ 12633565c898SBarry Smith PetscErrorCode SNESSetUseMatrixFree(SNES snes,PetscBool mf_operator,PetscBool mf) 12643565c898SBarry Smith { 12653565c898SBarry Smith PetscFunctionBegin; 12663565c898SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 126788b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes,mf_operator,2); 126888b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes,mf,3); 12694ddffce6SLisandro Dalcin snes->mf = mf_operator ? PETSC_TRUE : mf; 12703565c898SBarry Smith snes->mf_operator = mf_operator; 12713565c898SBarry Smith PetscFunctionReturn(0); 12723565c898SBarry Smith } 12733565c898SBarry Smith 12743565c898SBarry Smith /*@ 1275ec5066bdSBarry Smith SNESGetUseMatrixFree - indicates if the SNES uses matrix free finite difference matrix vector products to apply the Jacobian. 12763565c898SBarry Smith 12773565c898SBarry Smith Collective on SNES 12783565c898SBarry Smith 12793565c898SBarry Smith Input Parameter: 12803565c898SBarry Smith . snes - SNES context 12813565c898SBarry Smith 12823565c898SBarry Smith Output Parameters: 12834ddffce6SLisandro Dalcin + mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used 12844ddffce6SLisandro 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 12853565c898SBarry Smith 12863565c898SBarry Smith Options Database: 12873565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator 12883565c898SBarry Smith - -snes_mf_operator - use matrix free only for the mat operator 12893565c898SBarry Smith 12903565c898SBarry Smith Level: intermediate 12913565c898SBarry Smith 12923565c898SBarry Smith .seealso: SNESSetUseMatrixFree(), MatCreateSNESMF() 12933565c898SBarry Smith @*/ 12943565c898SBarry Smith PetscErrorCode SNESGetUseMatrixFree(SNES snes,PetscBool *mf_operator,PetscBool *mf) 12953565c898SBarry Smith { 12963565c898SBarry Smith PetscFunctionBegin; 12973565c898SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12983565c898SBarry Smith if (mf) *mf = snes->mf; 12993565c898SBarry Smith if (mf_operator) *mf_operator = snes->mf_operator; 13003565c898SBarry Smith PetscFunctionReturn(0); 13013565c898SBarry Smith } 13023565c898SBarry Smith 13033565c898SBarry Smith /*@ 1304c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 1305c8228a4eSBarry Smith at this time. 13069b94acceSBarry Smith 1307c7afd0dbSLois Curfman McInnes Not Collective 1308c7afd0dbSLois Curfman McInnes 13099b94acceSBarry Smith Input Parameter: 13109b94acceSBarry Smith . snes - SNES context 13119b94acceSBarry Smith 13129b94acceSBarry Smith Output Parameter: 13139b94acceSBarry Smith . iter - iteration number 13149b94acceSBarry Smith 1315c8228a4eSBarry Smith Notes: 1316c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 1317c8228a4eSBarry Smith 1318c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 131908405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 132008405cd6SLois Curfman McInnes .vb 132108405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 132208405cd6SLois Curfman McInnes if (!(it % 2)) { 132308405cd6SLois Curfman McInnes [compute Jacobian here] 132408405cd6SLois Curfman McInnes } 132508405cd6SLois Curfman McInnes .ve 1326c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 132708405cd6SLois Curfman McInnes recomputed every second SNES iteration. 1328c8228a4eSBarry Smith 1329c04deec6SBarry Smith After the SNES solve is complete this will return the number of nonlinear iterations used. 1330c04deec6SBarry Smith 133136851e7fSLois Curfman McInnes Level: intermediate 133236851e7fSLois Curfman McInnes 133371dbe336SPeter Brune .seealso: SNESGetLinearSolveIterations() 13349b94acceSBarry Smith @*/ 13357087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt *iter) 13369b94acceSBarry Smith { 13373a40ed3dSBarry Smith PetscFunctionBegin; 13380700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13394482741eSBarry Smith PetscValidIntPointer(iter,2); 13409b94acceSBarry Smith *iter = snes->iter; 13413a40ed3dSBarry Smith PetscFunctionReturn(0); 13429b94acceSBarry Smith } 134374679c65SBarry Smith 1344360c497dSPeter Brune /*@ 1345360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 1346360c497dSPeter Brune 1347360c497dSPeter Brune Not Collective 1348360c497dSPeter Brune 1349360c497dSPeter Brune Input Parameter: 1350a2b725a8SWilliam Gropp + snes - SNES context 1351a2b725a8SWilliam Gropp - iter - iteration number 1352360c497dSPeter Brune 1353360c497dSPeter Brune Level: developer 1354360c497dSPeter Brune 135571dbe336SPeter Brune .seealso: SNESGetLinearSolveIterations() 1356360c497dSPeter Brune @*/ 1357360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 1358360c497dSPeter Brune { 1359360c497dSPeter Brune PetscErrorCode ierr; 1360360c497dSPeter Brune 1361360c497dSPeter Brune PetscFunctionBegin; 1362360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1363e04113cfSBarry Smith ierr = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr); 1364360c497dSPeter Brune snes->iter = iter; 1365e04113cfSBarry Smith ierr = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr); 1366360c497dSPeter Brune PetscFunctionReturn(0); 1367360c497dSPeter Brune } 1368360c497dSPeter Brune 13699b94acceSBarry Smith /*@ 1370b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 13719b94acceSBarry Smith attempted by the nonlinear solver. 13729b94acceSBarry Smith 1373c7afd0dbSLois Curfman McInnes Not Collective 1374c7afd0dbSLois Curfman McInnes 13759b94acceSBarry Smith Input Parameter: 13769b94acceSBarry Smith . snes - SNES context 13779b94acceSBarry Smith 13789b94acceSBarry Smith Output Parameter: 13799b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 13809b94acceSBarry Smith 1381c96a6f78SLois Curfman McInnes Notes: 1382c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1383c96a6f78SLois Curfman McInnes 138436851e7fSLois Curfman McInnes Level: intermediate 138536851e7fSLois Curfman McInnes 1386e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 138758ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 13889b94acceSBarry Smith @*/ 13897087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt *nfails) 13909b94acceSBarry Smith { 13913a40ed3dSBarry Smith PetscFunctionBegin; 13920700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13934482741eSBarry Smith PetscValidIntPointer(nfails,2); 139450ffb88aSMatthew Knepley *nfails = snes->numFailures; 139550ffb88aSMatthew Knepley PetscFunctionReturn(0); 139650ffb88aSMatthew Knepley } 139750ffb88aSMatthew Knepley 139850ffb88aSMatthew Knepley /*@ 1399b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 140050ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 140150ffb88aSMatthew Knepley 140250ffb88aSMatthew Knepley Not Collective 140350ffb88aSMatthew Knepley 140450ffb88aSMatthew Knepley Input Parameters: 140550ffb88aSMatthew Knepley + snes - SNES context 140650ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 140750ffb88aSMatthew Knepley 140850ffb88aSMatthew Knepley Level: intermediate 140950ffb88aSMatthew Knepley 1410e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 141158ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 141250ffb88aSMatthew Knepley @*/ 14137087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 141450ffb88aSMatthew Knepley { 141550ffb88aSMatthew Knepley PetscFunctionBegin; 14160700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 141750ffb88aSMatthew Knepley snes->maxFailures = maxFails; 141850ffb88aSMatthew Knepley PetscFunctionReturn(0); 141950ffb88aSMatthew Knepley } 142050ffb88aSMatthew Knepley 142150ffb88aSMatthew Knepley /*@ 1422b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 142350ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 142450ffb88aSMatthew Knepley 142550ffb88aSMatthew Knepley Not Collective 142650ffb88aSMatthew Knepley 142750ffb88aSMatthew Knepley Input Parameter: 142850ffb88aSMatthew Knepley . snes - SNES context 142950ffb88aSMatthew Knepley 143050ffb88aSMatthew Knepley Output Parameter: 143150ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 143250ffb88aSMatthew Knepley 143350ffb88aSMatthew Knepley Level: intermediate 143450ffb88aSMatthew Knepley 1435e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 143658ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 143758ebbce7SBarry Smith 143850ffb88aSMatthew Knepley @*/ 14397087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 144050ffb88aSMatthew Knepley { 144150ffb88aSMatthew Knepley PetscFunctionBegin; 14420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14434482741eSBarry Smith PetscValidIntPointer(maxFails,2); 144450ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 14453a40ed3dSBarry Smith PetscFunctionReturn(0); 14469b94acceSBarry Smith } 1447a847f771SSatish Balay 14482541af92SBarry Smith /*@ 14492541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 14502541af92SBarry Smith done by SNES. 14512541af92SBarry Smith 14522541af92SBarry Smith Not Collective 14532541af92SBarry Smith 14542541af92SBarry Smith Input Parameter: 14552541af92SBarry Smith . snes - SNES context 14562541af92SBarry Smith 14572541af92SBarry Smith Output Parameter: 14582541af92SBarry Smith . nfuncs - number of evaluations 14592541af92SBarry Smith 14602541af92SBarry Smith Level: intermediate 14612541af92SBarry Smith 146295452b02SPatrick Sanan Notes: 146395452b02SPatrick Sanan Reset every time SNESSolve is called unless SNESSetCountersReset() is used. 1464971e163fSPeter Brune 1465971e163fSPeter Brune .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), SNESSetCountersReset() 14662541af92SBarry Smith @*/ 14677087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 14682541af92SBarry Smith { 14692541af92SBarry Smith PetscFunctionBegin; 14700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14712541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 14722541af92SBarry Smith *nfuncs = snes->nfuncs; 14732541af92SBarry Smith PetscFunctionReturn(0); 14742541af92SBarry Smith } 14752541af92SBarry Smith 14763d4c4710SBarry Smith /*@ 14773d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 14783d4c4710SBarry Smith linear solvers. 14793d4c4710SBarry Smith 14803d4c4710SBarry Smith Not Collective 14813d4c4710SBarry Smith 14823d4c4710SBarry Smith Input Parameter: 14833d4c4710SBarry Smith . snes - SNES context 14843d4c4710SBarry Smith 14853d4c4710SBarry Smith Output Parameter: 14863d4c4710SBarry Smith . nfails - number of failed solves 14873d4c4710SBarry Smith 14889d85da0cSMatthew G. Knepley Level: intermediate 14899d85da0cSMatthew G. Knepley 14909d85da0cSMatthew G. Knepley Options Database Keys: 14919d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 14929d85da0cSMatthew G. Knepley 14933d4c4710SBarry Smith Notes: 14943d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 14953d4c4710SBarry Smith 1496e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 14973d4c4710SBarry Smith @*/ 14987087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt *nfails) 14993d4c4710SBarry Smith { 15003d4c4710SBarry Smith PetscFunctionBegin; 15010700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15023d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 15033d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 15043d4c4710SBarry Smith PetscFunctionReturn(0); 15053d4c4710SBarry Smith } 15063d4c4710SBarry Smith 15073d4c4710SBarry Smith /*@ 15083d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 15093d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 15103d4c4710SBarry Smith 15113f9fe445SBarry Smith Logically Collective on SNES 15123d4c4710SBarry Smith 15133d4c4710SBarry Smith Input Parameters: 15143d4c4710SBarry Smith + snes - SNES context 15153d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 15163d4c4710SBarry Smith 15173d4c4710SBarry Smith Level: intermediate 15183d4c4710SBarry Smith 15199d85da0cSMatthew G. Knepley Options Database Keys: 15209d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 15219d85da0cSMatthew G. Knepley 152295452b02SPatrick Sanan Notes: 152395452b02SPatrick Sanan By default this is 0; that is SNES returns on the first failed linear solve 15243d4c4710SBarry Smith 152558ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 15263d4c4710SBarry Smith @*/ 15277087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 15283d4c4710SBarry Smith { 15293d4c4710SBarry Smith PetscFunctionBegin; 15300700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1531c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 15323d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 15333d4c4710SBarry Smith PetscFunctionReturn(0); 15343d4c4710SBarry Smith } 15353d4c4710SBarry Smith 15363d4c4710SBarry Smith /*@ 15373d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 15383d4c4710SBarry Smith are allowed before SNES terminates 15393d4c4710SBarry Smith 15403d4c4710SBarry Smith Not Collective 15413d4c4710SBarry Smith 15423d4c4710SBarry Smith Input Parameter: 15433d4c4710SBarry Smith . snes - SNES context 15443d4c4710SBarry Smith 15453d4c4710SBarry Smith Output Parameter: 15463d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 15473d4c4710SBarry Smith 15483d4c4710SBarry Smith Level: intermediate 15493d4c4710SBarry Smith 155095452b02SPatrick Sanan Notes: 155195452b02SPatrick Sanan By default this is 1; that is SNES returns on the first failed linear solve 15523d4c4710SBarry Smith 1553e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 15543d4c4710SBarry Smith @*/ 15557087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 15563d4c4710SBarry Smith { 15573d4c4710SBarry Smith PetscFunctionBegin; 15580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15593d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 15603d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 15613d4c4710SBarry Smith PetscFunctionReturn(0); 15623d4c4710SBarry Smith } 15633d4c4710SBarry Smith 1564c96a6f78SLois Curfman McInnes /*@ 1565b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1566c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1567c96a6f78SLois Curfman McInnes 1568c7afd0dbSLois Curfman McInnes Not Collective 1569c7afd0dbSLois Curfman McInnes 1570c96a6f78SLois Curfman McInnes Input Parameter: 1571c96a6f78SLois Curfman McInnes . snes - SNES context 1572c96a6f78SLois Curfman McInnes 1573c96a6f78SLois Curfman McInnes Output Parameter: 1574c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1575c96a6f78SLois Curfman McInnes 1576c96a6f78SLois Curfman McInnes Notes: 1577971e163fSPeter Brune This counter is reset to zero for each successive call to SNESSolve() unless SNESSetCountersReset() is used. 1578c96a6f78SLois Curfman McInnes 1579010be392SBarry 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 1580010be392SBarry Smith then call KSPGetIterationNumber() after the failed solve. 1581010be392SBarry Smith 158236851e7fSLois Curfman McInnes Level: intermediate 158336851e7fSLois Curfman McInnes 158471dbe336SPeter Brune .seealso: SNESGetIterationNumber(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESSetCountersReset() 1585c96a6f78SLois Curfman McInnes @*/ 15867087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt *lits) 1587c96a6f78SLois Curfman McInnes { 15883a40ed3dSBarry Smith PetscFunctionBegin; 15890700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15904482741eSBarry Smith PetscValidIntPointer(lits,2); 1591c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 15923a40ed3dSBarry Smith PetscFunctionReturn(0); 1593c96a6f78SLois Curfman McInnes } 1594c96a6f78SLois Curfman McInnes 1595971e163fSPeter Brune /*@ 1596971e163fSPeter Brune SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations 1597971e163fSPeter Brune are reset every time SNESSolve() is called. 1598971e163fSPeter Brune 1599971e163fSPeter Brune Logically Collective on SNES 1600971e163fSPeter Brune 1601971e163fSPeter Brune Input Parameter: 1602971e163fSPeter Brune + snes - SNES context 1603971e163fSPeter Brune - reset - whether to reset the counters or not 1604971e163fSPeter Brune 1605971e163fSPeter Brune Notes: 1606fa19ca70SBarry Smith This defaults to PETSC_TRUE 1607971e163fSPeter Brune 1608971e163fSPeter Brune Level: developer 1609971e163fSPeter Brune 1610734794cfSBarry Smith .seealso: SNESGetNumberFunctionEvals(), SNESGetLinearSolveIterations(), SNESGetNPC() 1611971e163fSPeter Brune @*/ 1612971e163fSPeter Brune PetscErrorCode SNESSetCountersReset(SNES snes,PetscBool reset) 1613971e163fSPeter Brune { 1614971e163fSPeter Brune PetscFunctionBegin; 1615971e163fSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1616971e163fSPeter Brune PetscValidLogicalCollectiveBool(snes,reset,2); 1617971e163fSPeter Brune snes->counters_reset = reset; 1618971e163fSPeter Brune PetscFunctionReturn(0); 1619971e163fSPeter Brune } 1620971e163fSPeter Brune 162182bf6240SBarry Smith 16222999313aSBarry Smith /*@ 16232999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 16242999313aSBarry Smith 16252999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 16262999313aSBarry Smith 16272999313aSBarry Smith Input Parameters: 16282999313aSBarry Smith + snes - the SNES context 16292999313aSBarry Smith - ksp - the KSP context 16302999313aSBarry Smith 16312999313aSBarry Smith Notes: 16322999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 16332999313aSBarry Smith so this routine is rarely needed. 16342999313aSBarry Smith 16352999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 16362999313aSBarry Smith decreased by one. 16372999313aSBarry Smith 16382999313aSBarry Smith Level: developer 16392999313aSBarry Smith 16402999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 16412999313aSBarry Smith @*/ 16427087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 16432999313aSBarry Smith { 16442999313aSBarry Smith PetscErrorCode ierr; 16452999313aSBarry Smith 16462999313aSBarry Smith PetscFunctionBegin; 16470700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16480700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 16492999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 16507dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1651906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 16522999313aSBarry Smith snes->ksp = ksp; 16532999313aSBarry Smith PetscFunctionReturn(0); 16542999313aSBarry Smith } 16552999313aSBarry Smith 16569b94acceSBarry Smith /* -----------------------------------------------------------*/ 165752baeb72SSatish Balay /*@ 16589b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 16599b94acceSBarry Smith 1660d083f849SBarry Smith Collective 1661c7afd0dbSLois Curfman McInnes 1662c7afd0dbSLois Curfman McInnes Input Parameters: 1663906ed7ccSBarry Smith . comm - MPI communicator 16649b94acceSBarry Smith 16659b94acceSBarry Smith Output Parameter: 16669b94acceSBarry Smith . outsnes - the new SNES context 16679b94acceSBarry Smith 1668c7afd0dbSLois Curfman McInnes Options Database Keys: 1669c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1670c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1671c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1672c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1673c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1674c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1675c1f60f51SBarry Smith 167636851e7fSLois Curfman McInnes Level: beginner 167736851e7fSLois Curfman McInnes 167895452b02SPatrick Sanan Developer Notes: 167995452b02SPatrick Sanan SNES always creates a KSP object even though many SNES methods do not use it. This is 1680efd4aadfSBarry Smith unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the 1681efd4aadfSBarry Smith particular method does use KSP and regulates if the information about the KSP is printed 1682efd4aadfSBarry Smith in SNESView(). TSSetFromOptions() does call SNESSetFromOptions() which can lead to users being confused 1683efd4aadfSBarry Smith by help messages about meaningless SNES options. 1684efd4aadfSBarry Smith 1685efd4aadfSBarry Smith SNES always creates the snes->kspconvctx even though it is used by only one type. This should 1686efd4aadfSBarry Smith be fixed. 1687efd4aadfSBarry Smith 16883d5a8a6aSBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner(), SNESSetLagJacobian() 1689a8054027SBarry Smith 16909b94acceSBarry Smith @*/ 16917087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 16929b94acceSBarry Smith { 1693dfbe8321SBarry Smith PetscErrorCode ierr; 16949b94acceSBarry Smith SNES snes; 1695fa9f3622SBarry Smith SNESKSPEW *kctx; 169637fcc0dbSBarry Smith 16973a40ed3dSBarry Smith PetscFunctionBegin; 1698ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 16990298fd71SBarry Smith *outsnes = NULL; 1700607a6623SBarry Smith ierr = SNESInitializePackage();CHKERRQ(ierr); 17018ba1e511SMatthew Knepley 170273107ff1SLisandro Dalcin ierr = PetscHeaderCreate(snes,SNES_CLASSID,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 17037adad957SLisandro Dalcin 17048d359177SBarry Smith snes->ops->converged = SNESConvergedDefault; 17052c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 170688976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 17079b94acceSBarry Smith snes->max_its = 50; 17089750a799SBarry Smith snes->max_funcs = 10000; 17099b94acceSBarry Smith snes->norm = 0.0; 1710c1e67a49SFande Kong snes->xnorm = 0.0; 1711c1e67a49SFande Kong snes->ynorm = 0.0; 1712365a6726SPeter Brune snes->normschedule = SNES_NORM_ALWAYS; 17136c67d002SPeter Brune snes->functype = SNES_FUNCTION_DEFAULT; 17143a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 17153a2046daSBarry Smith snes->rtol = 1.e-5; 17163a2046daSBarry Smith #else 1717b4874afaSBarry Smith snes->rtol = 1.e-8; 17183a2046daSBarry Smith #endif 1719b4874afaSBarry Smith snes->ttol = 0.0; 17203a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 17213a2046daSBarry Smith snes->abstol = 1.e-25; 17223a2046daSBarry Smith #else 172370441072SBarry Smith snes->abstol = 1.e-50; 17243a2046daSBarry Smith #endif 17257cd0ae37SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE) 17267cd0ae37SLisandro Dalcin snes->stol = 1.e-5; 17277cd0ae37SLisandro Dalcin #else 1728c60f73f4SPeter Brune snes->stol = 1.e-8; 17297cd0ae37SLisandro Dalcin #endif 17303a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 17313a2046daSBarry Smith snes->deltatol = 1.e-6; 17323a2046daSBarry Smith #else 17334b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 17343a2046daSBarry Smith #endif 1735e37c518bSBarry Smith snes->divtol = 1.e4; 1736e37c518bSBarry Smith snes->rnorm0 = 0; 17379b94acceSBarry Smith snes->nfuncs = 0; 173850ffb88aSMatthew Knepley snes->numFailures = 0; 173950ffb88aSMatthew Knepley snes->maxFailures = 1; 17407a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1741e35cf81dSBarry Smith snes->lagjacobian = 1; 174237ec4e1aSPeter Brune snes->jac_iter = 0; 174337ec4e1aSPeter Brune snes->lagjac_persist = PETSC_FALSE; 1744a8054027SBarry Smith snes->lagpreconditioner = 1; 174537ec4e1aSPeter Brune snes->pre_iter = 0; 174637ec4e1aSPeter Brune snes->lagpre_persist = PETSC_FALSE; 1747639f9d9dSBarry Smith snes->numbermonitors = 0; 17489e5d0892SLisandro Dalcin snes->data = NULL; 17494dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1750186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 17516f24a144SLois Curfman McInnes snes->nwork = 0; 17529e5d0892SLisandro Dalcin snes->work = NULL; 175358c9b817SLisandro Dalcin snes->nvwork = 0; 17549e5d0892SLisandro Dalcin snes->vwork = NULL; 1755758f92a0SBarry Smith snes->conv_hist_len = 0; 1756758f92a0SBarry Smith snes->conv_hist_max = 0; 17570298fd71SBarry Smith snes->conv_hist = NULL; 17580298fd71SBarry Smith snes->conv_hist_its = NULL; 1759758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1760971e163fSPeter Brune snes->counters_reset = PETSC_TRUE; 1761e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1762184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 1763efd4aadfSBarry Smith snes->npcside = PC_RIGHT; 1764b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled = 0; 1765c40d0f55SPeter Brune 1766d8f46077SPeter Brune snes->mf = PETSC_FALSE; 1767d8f46077SPeter Brune snes->mf_operator = PETSC_FALSE; 1768d8f46077SPeter Brune snes->mf_version = 1; 1769d8f46077SPeter Brune 17703d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 17713d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 17723d4c4710SBarry Smith 1773349187a7SBarry Smith snes->vizerotolerance = 1.e-8; 177476bd3646SJed Brown snes->checkjacdomainerror = PetscDefined(USE_DEBUG) ? PETSC_TRUE : PETSC_FALSE; 1775349187a7SBarry Smith 17764fc747eaSLawrence Mitchell /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */ 17774fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 17784fc747eaSLawrence Mitchell 17799b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 1780b00a9115SJed Brown ierr = PetscNewLog(snes,&kctx);CHKERRQ(ierr); 1781f5af7f23SKarl Rupp 17829b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 17839b94acceSBarry Smith kctx->version = 2; 17849b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 17859b94acceSBarry Smith this was too large for some test cases */ 178675567043SBarry Smith kctx->rtol_last = 0.0; 17879b94acceSBarry Smith kctx->rtol_max = .9; 17889b94acceSBarry Smith kctx->gamma = 1.0; 178962d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 179071f87433Sdalcinl kctx->alpha2 = kctx->alpha; 17919b94acceSBarry Smith kctx->threshold = .1; 179275567043SBarry Smith kctx->lresid_last = 0.0; 179375567043SBarry Smith kctx->norm_last = 0.0; 17949b94acceSBarry Smith 17959b94acceSBarry Smith *outsnes = snes; 17963a40ed3dSBarry Smith PetscFunctionReturn(0); 17979b94acceSBarry Smith } 17989b94acceSBarry Smith 179988f0584fSBarry Smith /*MC 1800411c0326SBarry Smith SNESFunction - Functional form used to convey the nonlinear function to be solved by SNES 180188f0584fSBarry Smith 180288f0584fSBarry Smith Synopsis: 1803411c0326SBarry Smith #include "petscsnes.h" 1804411c0326SBarry Smith PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx); 180588f0584fSBarry Smith 18061843f636SBarry Smith Collective on snes 18071843f636SBarry Smith 180888f0584fSBarry Smith Input Parameters: 180988f0584fSBarry Smith + snes - the SNES context 181088f0584fSBarry Smith . x - state at which to evaluate residual 181188f0584fSBarry Smith - ctx - optional user-defined function context, passed in with SNESSetFunction() 181288f0584fSBarry Smith 181388f0584fSBarry Smith Output Parameter: 181488f0584fSBarry Smith . f - vector to put residual (function value) 181588f0584fSBarry Smith 1816878cb397SSatish Balay Level: intermediate 1817878cb397SSatish Balay 181888f0584fSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 181988f0584fSBarry Smith M*/ 182088f0584fSBarry Smith 18219b94acceSBarry Smith /*@C 18229b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 18239b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 18249b94acceSBarry Smith equations. 18259b94acceSBarry Smith 18263f9fe445SBarry Smith Logically Collective on SNES 1827fee21e36SBarry Smith 1828c7afd0dbSLois Curfman McInnes Input Parameters: 1829c7afd0dbSLois Curfman McInnes + snes - the SNES context 1830c7afd0dbSLois Curfman McInnes . r - vector to store function value 1831f8b49ee9SBarry Smith . f - function evaluation routine; see SNESFunction for calling sequence details 1832c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 18330298fd71SBarry Smith function evaluation routine (may be NULL) 18349b94acceSBarry Smith 18359b94acceSBarry Smith Notes: 18369b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 18379b94acceSBarry Smith $ f'(x) x = -f(x), 1838c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 18399b94acceSBarry Smith 184036851e7fSLois Curfman McInnes Level: beginner 184136851e7fSLois Curfman McInnes 1842bf388a1fSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard(), SNESFunction 18439b94acceSBarry Smith @*/ 1844f8b49ee9SBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx) 18459b94acceSBarry Smith { 184685385478SLisandro Dalcin PetscErrorCode ierr; 18476cab3a1bSJed Brown DM dm; 18486cab3a1bSJed Brown 18493a40ed3dSBarry Smith PetscFunctionBegin; 18500700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1851d2a683ecSLisandro Dalcin if (r) { 1852d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1853d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 185485385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 18556bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 1856f5af7f23SKarl Rupp 185785385478SLisandro Dalcin snes->vec_func = r; 1858d2a683ecSLisandro Dalcin } 18596cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1860f8b49ee9SBarry Smith ierr = DMSNESSetFunction(dm,f,ctx);CHKERRQ(ierr); 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 216525acbd8eSLisandro Dalcin PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 21668b0a5094SBarry Smith { 21678b0a5094SBarry Smith PetscErrorCode ierr; 2168e03ab78fSPeter Brune DM dm; 2169942e3340SBarry Smith DMSNES sdm; 21706cab3a1bSJed Brown 21718b0a5094SBarry Smith PetscFunctionBegin; 2172e03ab78fSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2173942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 217425acbd8eSLisandro Dalcin if (!sdm->ops->computepfunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard function."); 217525acbd8eSLisandro Dalcin if (!sdm->ops->computepjacobian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard Jacobian."); 21768b0a5094SBarry Smith /* A(x)*x - b(x) */ 217725acbd8eSLisandro Dalcin PetscStackPush("SNES Picard user function"); 217822c6f798SBarry Smith ierr = (*sdm->ops->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr); 217925acbd8eSLisandro Dalcin PetscStackPop; 218025acbd8eSLisandro Dalcin PetscStackPush("SNES Picard user Jacobian"); 2181d1e9a80fSBarry Smith ierr = (*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx);CHKERRQ(ierr); 218225acbd8eSLisandro Dalcin PetscStackPop; 21838b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 218495eabcedSBarry Smith ierr = MatMultAdd(snes->jacobian,x,f,f);CHKERRQ(ierr); 21858b0a5094SBarry Smith PetscFunctionReturn(0); 21868b0a5094SBarry Smith } 21878b0a5094SBarry Smith 218825acbd8eSLisandro Dalcin PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat J,Mat B,void *ctx) 21898b0a5094SBarry Smith { 21908b0a5094SBarry Smith PetscFunctionBegin; 2191e03ab78fSPeter Brune /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */ 21928b0a5094SBarry Smith PetscFunctionReturn(0); 21938b0a5094SBarry Smith } 21948b0a5094SBarry Smith 21958b0a5094SBarry Smith /*@C 21960d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 21978b0a5094SBarry Smith 21988b0a5094SBarry Smith Logically Collective on SNES 21998b0a5094SBarry Smith 22008b0a5094SBarry Smith Input Parameters: 22018b0a5094SBarry Smith + snes - the SNES context 22028b0a5094SBarry Smith . r - vector to store function value 2203f8b49ee9SBarry Smith . b - function evaluation routine 2204e5d3d808SBarry Smith . Amat - matrix with which A(x) x - b(x) is to be computed 2205e5d3d808SBarry Smith . Pmat - matrix from which preconditioner is computed (usually the same as Amat) 2206411c0326SBarry Smith . J - function to compute matrix value, see SNESJacobianFunction for details on its calling sequence 22078b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 22080298fd71SBarry Smith function evaluation routine (may be NULL) 22098b0a5094SBarry Smith 22108b0a5094SBarry Smith Notes: 2211f450aa47SBarry 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 2212f450aa47SBarry 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. 2213f450aa47SBarry Smith 22148b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 22158b0a5094SBarry Smith 22168b0a5094SBarry 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} 22178b0a5094SBarry 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. 22188b0a5094SBarry Smith 22198b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 22208b0a5094SBarry Smith 22210d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 22220d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 22238b0a5094SBarry Smith 22248b0a5094SBarry 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 22258b0a5094SBarry 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 22268b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 22278b0a5094SBarry Smith 2228f450aa47SBarry Smith Level: intermediate 22298b0a5094SBarry Smith 2230411c0326SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard(), SNESJacobianFunction 22318b0a5094SBarry Smith @*/ 2232d1e9a80fSBarry Smith PetscErrorCode SNESSetPicard(SNES snes,Vec r,PetscErrorCode (*b)(SNES,Vec,Vec,void*),Mat Amat, Mat Pmat, PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx) 22338b0a5094SBarry Smith { 22348b0a5094SBarry Smith PetscErrorCode ierr; 2235e03ab78fSPeter Brune DM dm; 2236e03ab78fSPeter Brune 22378b0a5094SBarry Smith PetscFunctionBegin; 22388b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2239e03ab78fSPeter Brune ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 2240f8b49ee9SBarry Smith ierr = DMSNESSetPicard(dm,b,J,ctx);CHKERRQ(ierr); 22418b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 2242e5d3d808SBarry Smith ierr = SNESSetJacobian(snes,Amat,Pmat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 22438b0a5094SBarry Smith PetscFunctionReturn(0); 22448b0a5094SBarry Smith } 22458b0a5094SBarry Smith 22467971a8bfSPeter Brune /*@C 22477971a8bfSPeter Brune SNESGetPicard - Returns the context for the Picard iteration 22487971a8bfSPeter Brune 22497971a8bfSPeter Brune Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 22507971a8bfSPeter Brune 22517971a8bfSPeter Brune Input Parameter: 22527971a8bfSPeter Brune . snes - the SNES context 22537971a8bfSPeter Brune 22547971a8bfSPeter Brune Output Parameter: 22550298fd71SBarry Smith + r - the function (or NULL) 2256f8b49ee9SBarry Smith . f - the function (or NULL); see SNESFunction for calling sequence details 2257e4357dc4SBarry Smith . Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL) 2258e4357dc4SBarry Smith . Pmat - the matrix from which the preconditioner will be constructed (or NULL) 2259f8b49ee9SBarry Smith . J - the function for matrix evaluation (or NULL); see SNESJacobianFunction for calling sequence details 22600298fd71SBarry Smith - ctx - the function context (or NULL) 22617971a8bfSPeter Brune 22627971a8bfSPeter Brune Level: advanced 22637971a8bfSPeter Brune 2264e4357dc4SBarry Smith .seealso: SNESSetPicard(), SNESGetFunction(), SNESGetJacobian(), SNESGetDM(), SNESFunction, SNESJacobianFunction 22657971a8bfSPeter Brune @*/ 2266d1e9a80fSBarry 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) 22677971a8bfSPeter Brune { 22687971a8bfSPeter Brune PetscErrorCode ierr; 22697971a8bfSPeter Brune DM dm; 22707971a8bfSPeter Brune 22717971a8bfSPeter Brune PetscFunctionBegin; 22727971a8bfSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 22730298fd71SBarry Smith ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 2274e4357dc4SBarry Smith ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 22757971a8bfSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2276f8b49ee9SBarry Smith ierr = DMSNESGetPicard(dm,f,J,ctx);CHKERRQ(ierr); 22777971a8bfSPeter Brune PetscFunctionReturn(0); 22787971a8bfSPeter Brune } 22797971a8bfSPeter Brune 2280d25893d9SBarry Smith /*@C 2281d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 2282d25893d9SBarry Smith 2283d25893d9SBarry Smith Logically Collective on SNES 2284d25893d9SBarry Smith 2285d25893d9SBarry Smith Input Parameters: 2286d25893d9SBarry Smith + snes - the SNES context 2287d25893d9SBarry Smith . func - function evaluation routine 2288d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 22890298fd71SBarry Smith function evaluation routine (may be NULL) 2290d25893d9SBarry Smith 2291d25893d9SBarry Smith Calling sequence of func: 2292d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 2293d25893d9SBarry Smith 2294d25893d9SBarry Smith . f - function vector 2295d25893d9SBarry Smith - ctx - optional user-defined function context 2296d25893d9SBarry Smith 2297d25893d9SBarry Smith Level: intermediate 2298d25893d9SBarry Smith 2299d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 2300d25893d9SBarry Smith @*/ 2301d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 2302d25893d9SBarry Smith { 2303d25893d9SBarry Smith PetscFunctionBegin; 2304d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2305d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 2306d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 2307d25893d9SBarry Smith PetscFunctionReturn(0); 2308d25893d9SBarry Smith } 2309d25893d9SBarry Smith 23103ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 23111096aae1SMatthew Knepley /*@C 23121096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 23131096aae1SMatthew Knepley it assumes a zero right hand side. 23141096aae1SMatthew Knepley 23153f9fe445SBarry Smith Logically Collective on SNES 23161096aae1SMatthew Knepley 23171096aae1SMatthew Knepley Input Parameter: 23181096aae1SMatthew Knepley . snes - the SNES context 23191096aae1SMatthew Knepley 23201096aae1SMatthew Knepley Output Parameter: 23210298fd71SBarry Smith . rhs - the right hand side vector or NULL if the right hand side vector is null 23221096aae1SMatthew Knepley 23231096aae1SMatthew Knepley Level: intermediate 23241096aae1SMatthew Knepley 232585385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 23261096aae1SMatthew Knepley @*/ 23277087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 23281096aae1SMatthew Knepley { 23291096aae1SMatthew Knepley PetscFunctionBegin; 23300700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23311096aae1SMatthew Knepley PetscValidPointer(rhs,2); 233285385478SLisandro Dalcin *rhs = snes->vec_rhs; 23331096aae1SMatthew Knepley PetscFunctionReturn(0); 23341096aae1SMatthew Knepley } 23351096aae1SMatthew Knepley 23369b94acceSBarry Smith /*@ 2337bf388a1fSBarry Smith SNESComputeFunction - Calls the function that has been set with SNESSetFunction(). 23389b94acceSBarry Smith 2339c7afd0dbSLois Curfman McInnes Collective on SNES 2340c7afd0dbSLois Curfman McInnes 23419b94acceSBarry Smith Input Parameters: 2342c7afd0dbSLois Curfman McInnes + snes - the SNES context 2343c7afd0dbSLois Curfman McInnes - x - input vector 23449b94acceSBarry Smith 23459b94acceSBarry Smith Output Parameter: 23463638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 23479b94acceSBarry Smith 23481bffabb2SLois Curfman McInnes Notes: 234936851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 235036851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 235136851e7fSLois Curfman McInnes themselves. 235236851e7fSLois Curfman McInnes 235336851e7fSLois Curfman McInnes Level: developer 235436851e7fSLois Curfman McInnes 2355a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 23569b94acceSBarry Smith @*/ 23577087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 23589b94acceSBarry Smith { 2359dfbe8321SBarry Smith PetscErrorCode ierr; 23606cab3a1bSJed Brown DM dm; 2361942e3340SBarry Smith DMSNES sdm; 23629b94acceSBarry Smith 23633a40ed3dSBarry Smith PetscFunctionBegin; 23640700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23650700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 23660700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2367c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 2368c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 236962796dfbSBarry Smith ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr); 2370184914b5SBarry Smith 23716cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2372942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 237332f3f7c2SPeter Brune if (sdm->ops->computefunction) { 237494db00ebSBarry Smith if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) { 2375ccf3c845SPeter Brune ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 237694db00ebSBarry Smith } 23778860a134SJunchao Zhang ierr = VecLockReadPush(x);CHKERRQ(ierr); 2378d64ed03dSBarry Smith PetscStackPush("SNES user function"); 23798ddeebeaSSteve Benbow /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 23808ddeebeaSSteve Benbow snes->domainerror = PETSC_FALSE; 238122c6f798SBarry Smith ierr = (*sdm->ops->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 2382d64ed03dSBarry Smith PetscStackPop; 23838860a134SJunchao Zhang ierr = VecLockReadPop(x);CHKERRQ(ierr); 238494db00ebSBarry Smith if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) { 2385ccf3c845SPeter Brune ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 238694db00ebSBarry Smith } 2387c90fad12SPeter Brune } else if (snes->vec_rhs) { 2388c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 2389644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 239085385478SLisandro Dalcin if (snes->vec_rhs) { 239185385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 23923ab0aad5SBarry Smith } 2393ae3c334cSLois Curfman McInnes snes->nfuncs++; 2394422a814eSBarry Smith /* 2395422a814eSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2396422a814eSBarry Smith propagate the value to all processes 2397422a814eSBarry Smith */ 2398422a814eSBarry Smith if (snes->domainerror) { 2399422a814eSBarry Smith ierr = VecSetInf(y);CHKERRQ(ierr); 2400422a814eSBarry Smith } 24013a40ed3dSBarry Smith PetscFunctionReturn(0); 24029b94acceSBarry Smith } 24039b94acceSBarry Smith 2404c79ef259SPeter Brune /*@ 2405be95d8f1SBarry Smith SNESComputeNGS - Calls the Gauss-Seidel function that has been set with SNESSetNGS(). 2406c79ef259SPeter Brune 2407c79ef259SPeter Brune Collective on SNES 2408c79ef259SPeter Brune 2409c79ef259SPeter Brune Input Parameters: 2410c79ef259SPeter Brune + snes - the SNES context 2411c79ef259SPeter Brune . x - input vector 2412c79ef259SPeter Brune - b - rhs vector 2413c79ef259SPeter Brune 2414c79ef259SPeter Brune Output Parameter: 2415c79ef259SPeter Brune . x - new solution vector 2416c79ef259SPeter Brune 2417c79ef259SPeter Brune Notes: 2418be95d8f1SBarry Smith SNESComputeNGS() is typically used within composed nonlinear solver 2419c79ef259SPeter Brune implementations, so most users would not generally call this routine 2420c79ef259SPeter Brune themselves. 2421c79ef259SPeter Brune 2422c79ef259SPeter Brune Level: developer 2423c79ef259SPeter Brune 2424be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESComputeFunction() 2425c79ef259SPeter Brune @*/ 2426be95d8f1SBarry Smith PetscErrorCode SNESComputeNGS(SNES snes,Vec b,Vec x) 2427646217ecSPeter Brune { 2428646217ecSPeter Brune PetscErrorCode ierr; 24296cab3a1bSJed Brown DM dm; 2430942e3340SBarry Smith DMSNES sdm; 2431646217ecSPeter Brune 2432646217ecSPeter Brune PetscFunctionBegin; 2433646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2434646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2435646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 2436646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 2437646217ecSPeter Brune if (b) PetscCheckSameComm(snes,1,b,3); 243862796dfbSBarry Smith if (b) {ierr = VecValidValues(b,2,PETSC_TRUE);CHKERRQ(ierr);} 2439be95d8f1SBarry Smith ierr = PetscLogEventBegin(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr); 24406cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2441942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 244222c6f798SBarry Smith if (sdm->ops->computegs) { 24438860a134SJunchao Zhang if (b) {ierr = VecLockReadPush(b);CHKERRQ(ierr);} 2444be95d8f1SBarry Smith PetscStackPush("SNES user NGS"); 244522c6f798SBarry Smith ierr = (*sdm->ops->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 2446646217ecSPeter Brune PetscStackPop; 24478860a134SJunchao Zhang if (b) {ierr = VecLockReadPop(b);CHKERRQ(ierr);} 2448be95d8f1SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve()."); 2449be95d8f1SBarry Smith ierr = PetscLogEventEnd(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr); 2450646217ecSPeter Brune PetscFunctionReturn(0); 2451646217ecSPeter Brune } 2452646217ecSPeter Brune 2453e885f1abSBarry Smith PetscErrorCode SNESTestJacobian(SNES snes) 2454e885f1abSBarry Smith { 245512837594SBarry Smith Mat A,B,C,D,jacobian; 2456e885f1abSBarry Smith Vec x = snes->vec_sol,f = snes->vec_func; 2457e885f1abSBarry Smith PetscErrorCode ierr; 2458e885f1abSBarry Smith PetscReal nrm,gnorm; 245981e7118cSBarry Smith PetscReal threshold = 1.e-5; 24600e276705SLisandro Dalcin MatType mattype; 2461e885f1abSBarry Smith PetscInt m,n,M,N; 2462e885f1abSBarry Smith void *functx; 24632cd624f9SStefano Zampini PetscBool complete_print = PETSC_FALSE,threshold_print = PETSC_FALSE,test = PETSC_FALSE,flg,istranspose; 24643325ff46SBarry Smith PetscViewer viewer,mviewer; 2465e885f1abSBarry Smith MPI_Comm comm; 2466e885f1abSBarry Smith PetscInt tabs; 246712837594SBarry Smith static PetscBool directionsprinted = PETSC_FALSE; 24683325ff46SBarry Smith PetscViewerFormat format; 2469e885f1abSBarry Smith 2470e885f1abSBarry Smith PetscFunctionBegin; 2471fc35ed60SBarry Smith ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 247212837594SBarry Smith ierr = PetscOptionsName("-snes_test_jacobian","Compare hand-coded and finite difference Jacobians","None",&test);CHKERRQ(ierr); 247312837594SBarry Smith ierr = PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold,NULL);CHKERRQ(ierr); 24743325ff46SBarry 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); 247518d89885SKarl Rupp if (!complete_print) { 2476455a5933SJed Brown ierr = PetscOptionsDeprecated("-snes_test_jacobian_display","-snes_test_jacobian_view","3.13",NULL);CHKERRQ(ierr); 247718d89885SKarl Rupp ierr = PetscOptionsViewer("-snes_test_jacobian_display","Display difference between hand-coded and finite difference Jacobians","None",&mviewer,&format,&complete_print);CHKERRQ(ierr); 247818d89885SKarl Rupp } 247918d89885SKarl Rupp /* for compatibility with PETSc 3.9 and older. */ 2480455a5933SJed 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); 248118d89885SKarl 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); 2482e885f1abSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 2483e885f1abSBarry Smith if (!test) PetscFunctionReturn(0); 2484e885f1abSBarry Smith 2485e885f1abSBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2486e885f1abSBarry Smith ierr = PetscViewerASCIIGetStdout(comm,&viewer);CHKERRQ(ierr); 2487e885f1abSBarry Smith ierr = PetscViewerASCIIGetTab(viewer, &tabs);CHKERRQ(ierr); 2488e885f1abSBarry Smith ierr = PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel);CHKERRQ(ierr); 248912837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," ---------- Testing Jacobian -------------\n");CHKERRQ(ierr); 249012837594SBarry Smith if (!complete_print && !directionsprinted) { 249112837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n");CHKERRQ(ierr); 2492fc35ed60SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," of hand-coded and finite difference Jacobian entries greater than <threshold>.\n");CHKERRQ(ierr); 249312837594SBarry Smith } 249412837594SBarry Smith if (!directionsprinted) { 249512837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n");CHKERRQ(ierr); 2496e885f1abSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," O(1.e-8), the hand-coded Jacobian is probably correct.\n");CHKERRQ(ierr); 249712837594SBarry Smith directionsprinted = PETSC_TRUE; 2498e885f1abSBarry Smith } 24993325ff46SBarry Smith if (complete_print) { 25003325ff46SBarry Smith ierr = PetscViewerPushFormat(mviewer,format);CHKERRQ(ierr); 2501e885f1abSBarry Smith } 2502e885f1abSBarry Smith 250312837594SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)snes->jacobian,MATMFFD,&flg);CHKERRQ(ierr); 250412837594SBarry Smith if (!flg) jacobian = snes->jacobian; 250512837594SBarry Smith else jacobian = snes->jacobian_pre; 250612837594SBarry Smith 2507a82339d0SMatthew G. Knepley if (!x) { 2508a82339d0SMatthew G. Knepley ierr = MatCreateVecs(jacobian, &x, NULL);CHKERRQ(ierr); 2509a82339d0SMatthew G. Knepley } else { 2510a82339d0SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) x);CHKERRQ(ierr); 2511a82339d0SMatthew G. Knepley } 2512a82339d0SMatthew G. Knepley if (!f) { 2513a82339d0SMatthew G. Knepley ierr = VecDuplicate(x, &f);CHKERRQ(ierr); 2514a82339d0SMatthew G. Knepley } else { 2515a82339d0SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) f);CHKERRQ(ierr); 2516a82339d0SMatthew G. Knepley } 2517a82339d0SMatthew G. Knepley /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */ 2518a82339d0SMatthew G. Knepley ierr = SNESComputeFunction(snes,x,f);CHKERRQ(ierr); 2519a82339d0SMatthew G. Knepley ierr = VecDestroy(&f);CHKERRQ(ierr); 25202cd624f9SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)snes,SNESKSPTRANSPOSEONLY,&istranspose);CHKERRQ(ierr); 252112837594SBarry Smith while (jacobian) { 25222cd624f9SStefano Zampini Mat JT = NULL, Jsave = NULL; 25232cd624f9SStefano Zampini 25242cd624f9SStefano Zampini if (istranspose) { 25252cd624f9SStefano Zampini ierr = MatCreateTranspose(jacobian,&JT);CHKERRQ(ierr); 25262cd624f9SStefano Zampini Jsave = jacobian; 25272cd624f9SStefano Zampini jacobian = JT; 25282cd624f9SStefano Zampini } 25290e276705SLisandro Dalcin ierr = PetscObjectBaseTypeCompareAny((PetscObject)jacobian,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPISBAIJ,"");CHKERRQ(ierr); 253012837594SBarry Smith if (flg) { 253112837594SBarry Smith A = jacobian; 253212837594SBarry Smith ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 253312837594SBarry Smith } else { 25340bacdadaSStefano Zampini ierr = MatComputeOperator(jacobian,MATAIJ,&A);CHKERRQ(ierr); 253512837594SBarry Smith } 2536e885f1abSBarry Smith 25370e276705SLisandro Dalcin ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 2538e885f1abSBarry Smith ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 2539e885f1abSBarry Smith ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 25400e276705SLisandro Dalcin ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr); 25410e276705SLisandro Dalcin ierr = MatSetType(B,mattype);CHKERRQ(ierr); 2542e885f1abSBarry Smith ierr = MatSetSizes(B,m,n,M,N);CHKERRQ(ierr); 25430e276705SLisandro Dalcin ierr = MatSetBlockSizesFromMats(B,A,A);CHKERRQ(ierr); 2544e885f1abSBarry Smith ierr = MatSetUp(B);CHKERRQ(ierr); 2545e885f1abSBarry Smith ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 2546e885f1abSBarry Smith 2547e885f1abSBarry Smith ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr); 2548e885f1abSBarry Smith ierr = SNESComputeJacobianDefault(snes,x,B,B,functx);CHKERRQ(ierr); 254912837594SBarry Smith 255012837594SBarry Smith ierr = MatDuplicate(B,MAT_COPY_VALUES,&D);CHKERRQ(ierr); 255112837594SBarry Smith ierr = MatAYPX(D,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 255212837594SBarry Smith ierr = MatNorm(D,NORM_FROBENIUS,&nrm);CHKERRQ(ierr); 2553e885f1abSBarry Smith ierr = MatNorm(A,NORM_FROBENIUS,&gnorm);CHKERRQ(ierr); 255412837594SBarry Smith ierr = MatDestroy(&D);CHKERRQ(ierr); 255512837594SBarry Smith if (!gnorm) gnorm = 1; /* just in case */ 255612837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n",(double)(nrm/gnorm),(double)nrm);CHKERRQ(ierr); 255712837594SBarry Smith 2558e885f1abSBarry Smith if (complete_print) { 255912837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Hand-coded Jacobian ----------\n");CHKERRQ(ierr); 25601878987eSStefano Zampini ierr = MatView(A,mviewer);CHKERRQ(ierr); 256112837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Finite difference Jacobian ----------\n");CHKERRQ(ierr); 25623325ff46SBarry Smith ierr = MatView(B,mviewer);CHKERRQ(ierr); 2563e885f1abSBarry Smith } 2564e885f1abSBarry Smith 2565df10fb39SFande Kong if (threshold_print || complete_print) { 2566e885f1abSBarry Smith PetscInt Istart, Iend, *ccols, bncols, cncols, j, row; 2567e885f1abSBarry Smith PetscScalar *cvals; 2568e885f1abSBarry Smith const PetscInt *bcols; 2569e885f1abSBarry Smith const PetscScalar *bvals; 2570e885f1abSBarry Smith 2571e885f1abSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 25720e276705SLisandro Dalcin ierr = MatSetType(C,mattype);CHKERRQ(ierr); 2573e885f1abSBarry Smith ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr); 25740e276705SLisandro Dalcin ierr = MatSetBlockSizesFromMats(C,A,A);CHKERRQ(ierr); 2575e885f1abSBarry Smith ierr = MatSetUp(C);CHKERRQ(ierr); 2576e885f1abSBarry Smith ierr = MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 25770e276705SLisandro Dalcin 25780e276705SLisandro Dalcin ierr = MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 2579e885f1abSBarry Smith ierr = MatGetOwnershipRange(B,&Istart,&Iend);CHKERRQ(ierr); 2580e885f1abSBarry Smith 2581e885f1abSBarry Smith for (row = Istart; row < Iend; row++) { 2582e885f1abSBarry Smith ierr = MatGetRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr); 2583e885f1abSBarry Smith ierr = PetscMalloc2(bncols,&ccols,bncols,&cvals);CHKERRQ(ierr); 2584e885f1abSBarry Smith for (j = 0, cncols = 0; j < bncols; j++) { 258523a52b1dSBarry Smith if (PetscAbsScalar(bvals[j]) > threshold) { 2586e885f1abSBarry Smith ccols[cncols] = bcols[j]; 2587e885f1abSBarry Smith cvals[cncols] = bvals[j]; 2588e885f1abSBarry Smith cncols += 1; 2589e885f1abSBarry Smith } 2590e885f1abSBarry Smith } 2591e885f1abSBarry Smith if (cncols) { 2592e885f1abSBarry Smith ierr = MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES);CHKERRQ(ierr); 2593e885f1abSBarry Smith } 2594e885f1abSBarry Smith ierr = MatRestoreRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr); 2595e885f1abSBarry Smith ierr = PetscFree2(ccols,cvals);CHKERRQ(ierr); 2596e885f1abSBarry Smith } 2597e885f1abSBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2598e885f1abSBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 259912837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n",(double)threshold);CHKERRQ(ierr); 260018d89885SKarl Rupp ierr = MatView(C,complete_print ? mviewer : viewer);CHKERRQ(ierr); 2601e885f1abSBarry Smith ierr = MatDestroy(&C);CHKERRQ(ierr); 2602e885f1abSBarry Smith } 260312837594SBarry Smith ierr = MatDestroy(&A);CHKERRQ(ierr); 2604e885f1abSBarry Smith ierr = MatDestroy(&B);CHKERRQ(ierr); 26052cd624f9SStefano Zampini ierr = MatDestroy(&JT);CHKERRQ(ierr); 26062cd624f9SStefano Zampini if (Jsave) jacobian = Jsave; 260712837594SBarry Smith if (jacobian != snes->jacobian_pre) { 260812837594SBarry Smith jacobian = snes->jacobian_pre; 260912837594SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," ---------- Testing Jacobian for preconditioner -------------\n");CHKERRQ(ierr); 261012837594SBarry Smith } 261112837594SBarry Smith else jacobian = NULL; 261212837594SBarry Smith } 2613a82339d0SMatthew G. Knepley ierr = VecDestroy(&x);CHKERRQ(ierr); 26143325ff46SBarry Smith if (complete_print) { 26153325ff46SBarry Smith ierr = PetscViewerPopFormat(mviewer);CHKERRQ(ierr); 26163325ff46SBarry Smith } 2617a0c90127SFande Kong if (mviewer) { ierr = PetscViewerDestroy(&mviewer);CHKERRQ(ierr); } 2618e885f1abSBarry Smith ierr = PetscViewerASCIISetTab(viewer,tabs);CHKERRQ(ierr); 2619e885f1abSBarry Smith PetscFunctionReturn(0); 2620e885f1abSBarry Smith } 2621e885f1abSBarry Smith 262262fef451SLois Curfman McInnes /*@ 2623bf388a1fSBarry Smith SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian(). 262462fef451SLois Curfman McInnes 2625d083f849SBarry Smith Collective on SNES 2626c7afd0dbSLois Curfman McInnes 262762fef451SLois Curfman McInnes Input Parameters: 2628c7afd0dbSLois Curfman McInnes + snes - the SNES context 2629c7afd0dbSLois Curfman McInnes - x - input vector 263062fef451SLois Curfman McInnes 263162fef451SLois Curfman McInnes Output Parameters: 2632c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 2633d1e9a80fSBarry Smith - B - optional preconditioning matrix 2634fee21e36SBarry Smith 2635e35cf81dSBarry Smith Options Database Keys: 2636e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 2637693365a8SJed Brown . -snes_lag_jacobian <lag> 2638455a5933SJed 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. 2639455a5933SJed 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 2640693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 2641693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 2642693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 26434c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 264494d6a431SBarry Smith . -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference 2645c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 2646c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 2647c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2648c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 26494c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 2650c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 2651c01495d3SJed Brown 2652e35cf81dSBarry Smith 265362fef451SLois Curfman McInnes Notes: 265462fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 265562fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 265662fef451SLois Curfman McInnes 265795452b02SPatrick Sanan Developer Notes: 265895452b02SPatrick 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 2659e885f1abSBarry Smith for with the SNESType of test that has been removed. 2660e885f1abSBarry Smith 266136851e7fSLois Curfman McInnes Level: developer 266236851e7fSLois Curfman McInnes 2663e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 266462fef451SLois Curfman McInnes @*/ 2665d1e9a80fSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat A,Mat B) 26669b94acceSBarry Smith { 2667dfbe8321SBarry Smith PetscErrorCode ierr; 2668ace3abfcSBarry Smith PetscBool flag; 26696cab3a1bSJed Brown DM dm; 2670942e3340SBarry Smith DMSNES sdm; 2671e0e3a89bSBarry Smith KSP ksp; 26723a40ed3dSBarry Smith 26733a40ed3dSBarry Smith PetscFunctionBegin; 26740700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 26750700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2676c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 267762796dfbSBarry Smith ierr = VecValidValues(X,2,PETSC_TRUE);CHKERRQ(ierr); 26786cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2679942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 26803232da50SPeter Brune 2681ce94432eSBarry Smith if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 2682ebd3b9afSBarry Smith 2683ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 2684ebd3b9afSBarry Smith 2685fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 2686fe3ffe1eSBarry Smith snes->lagjacobian = -1; 2687f5af7f23SKarl Rupp 2688fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 2689fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 2690e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 269194ab13aaSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr); 2692ebd3b9afSBarry Smith if (flag) { 269394ab13aaSBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 269494ab13aaSBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2695ebd3b9afSBarry Smith } 2696e35cf81dSBarry Smith PetscFunctionReturn(0); 269737ec4e1aSPeter Brune } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) { 2698e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 269994ab13aaSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr); 2700ebd3b9afSBarry Smith if (flag) { 270194ab13aaSBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 270294ab13aaSBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2703ebd3b9afSBarry Smith } 2704e35cf81dSBarry Smith PetscFunctionReturn(0); 2705e35cf81dSBarry Smith } 2706efd4aadfSBarry Smith if (snes->npc && snes->npcside== PC_LEFT) { 270794ab13aaSBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 270894ab13aaSBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2709d728fb7dSPeter Brune PetscFunctionReturn(0); 2710d728fb7dSPeter Brune } 2711e35cf81dSBarry Smith 271294ab13aaSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr); 27138860a134SJunchao Zhang ierr = VecLockReadPush(X);CHKERRQ(ierr); 2714d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 2715d1e9a80fSBarry Smith ierr = (*sdm->ops->computejacobian)(snes,X,A,B,sdm->jacobianctx);CHKERRQ(ierr); 2716d64ed03dSBarry Smith PetscStackPop; 27178860a134SJunchao Zhang ierr = VecLockReadPop(X);CHKERRQ(ierr); 271894ab13aaSBarry Smith ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr); 271928d58a37SPierre Jolivet 272028d58a37SPierre Jolivet /* attach latest linearization point to the preconditioning matrix */ 272128d58a37SPierre Jolivet ierr = PetscObjectCompose((PetscObject)B,"__SNES_latest_X",(PetscObject)X);CHKERRQ(ierr); 2722a8054027SBarry Smith 2723e0e3a89bSBarry Smith /* the next line ensures that snes->ksp exists */ 2724e0e3a89bSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 27253b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 27263b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 2727d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr); 27283b4f5425SBarry Smith snes->lagpreconditioner = -1; 27293b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 2730a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 2731d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr); 273237ec4e1aSPeter Brune } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) { 2733a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 2734d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr); 2735d1e9a80fSBarry Smith } else { 2736d1e9a80fSBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner\n");CHKERRQ(ierr); 2737d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr); 2738a8054027SBarry Smith } 2739a8054027SBarry Smith 2740e885f1abSBarry Smith ierr = SNESTestJacobian(snes);CHKERRQ(ierr); 27416d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 274294ab13aaSBarry Smith /* PetscValidHeaderSpecific(A,MAT_CLASSID,3); 274394ab13aaSBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,4); */ 2744693365a8SJed Brown { 2745693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 274616413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit",NULL,NULL,&flag);CHKERRQ(ierr); 274716413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr); 274816413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr); 274916413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_operator",NULL,NULL,&flag_operator);CHKERRQ(ierr); 2750693365a8SJed Brown if (flag || flag_draw || flag_contour) { 27510298fd71SBarry Smith Mat Bexp_mine = NULL,Bexp,FDexp; 2752693365a8SJed Brown PetscViewer vdraw,vstdout; 27536b3a5b13SJed Brown PetscBool flg; 2754693365a8SJed Brown if (flag_operator) { 27550bacdadaSStefano Zampini ierr = MatComputeOperator(A,MATAIJ,&Bexp_mine);CHKERRQ(ierr); 2756693365a8SJed Brown Bexp = Bexp_mine; 2757693365a8SJed Brown } else { 2758693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 2759b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompareAny((PetscObject)B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 276094ab13aaSBarry Smith if (flg) Bexp = B; 2761693365a8SJed Brown else { 2762693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 27630bacdadaSStefano Zampini ierr = MatComputeOperator(B,MATAIJ,&Bexp_mine);CHKERRQ(ierr); 2764693365a8SJed Brown Bexp = Bexp_mine; 2765693365a8SJed Brown } 2766693365a8SJed Brown } 2767693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 2768d1e9a80fSBarry Smith ierr = SNESComputeJacobianDefault(snes,X,FDexp,FDexp,NULL);CHKERRQ(ierr); 2769ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr); 2770693365a8SJed Brown if (flag_draw || flag_contour) { 27719e5d0892SLisandro Dalcin ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2772693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 27730298fd71SBarry Smith } else vdraw = NULL; 2774693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian");CHKERRQ(ierr); 2775693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 2776693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 2777693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 2778693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2779693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 2780693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2781693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 2782693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2783693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 2784693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2785693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 2786693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2787693365a8SJed Brown } 2788693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2789693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2790693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 2791693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 2792693365a8SJed Brown } 2793693365a8SJed Brown } 27944c30e9fbSJed Brown { 27956719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 27966719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 279716413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring",NULL,NULL,&flag);CHKERRQ(ierr); 279816413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_display",NULL,NULL,&flag_display);CHKERRQ(ierr); 279916413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr); 280016413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr); 280116413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",NULL,NULL,&flag_threshold);CHKERRQ(ierr); 280227b0f280SBarry Smith if (flag_threshold) { 2803c5929fdfSBarry Smith ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL);CHKERRQ(ierr); 2804c5929fdfSBarry Smith ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL);CHKERRQ(ierr); 280527b0f280SBarry Smith } 28066719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 28074c30e9fbSJed Brown Mat Bfd; 28084c30e9fbSJed Brown PetscViewer vdraw,vstdout; 2809335efc43SPeter Brune MatColoring coloring; 28104c30e9fbSJed Brown ISColoring iscoloring; 28114c30e9fbSJed Brown MatFDColoring matfdcoloring; 28124c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 28134c30e9fbSJed Brown void *funcctx; 28146719d8e4SJed Brown PetscReal norm1,norm2,normmax; 28154c30e9fbSJed Brown 281694ab13aaSBarry Smith ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 2817335efc43SPeter Brune ierr = MatColoringCreate(Bfd,&coloring);CHKERRQ(ierr); 2818335efc43SPeter Brune ierr = MatColoringSetType(coloring,MATCOLORINGSL);CHKERRQ(ierr); 2819335efc43SPeter Brune ierr = MatColoringSetFromOptions(coloring);CHKERRQ(ierr); 2820335efc43SPeter Brune ierr = MatColoringApply(coloring,&iscoloring);CHKERRQ(ierr); 2821335efc43SPeter Brune ierr = MatColoringDestroy(&coloring);CHKERRQ(ierr); 28224c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 2823f86b9fbaSHong Zhang ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 2824f86b9fbaSHong Zhang ierr = MatFDColoringSetUp(Bfd,iscoloring,matfdcoloring);CHKERRQ(ierr); 28254c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 28264c30e9fbSJed Brown 28274c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 28280298fd71SBarry Smith ierr = SNESGetFunction(snes,NULL,&func,&funcctx);CHKERRQ(ierr); 28294c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr); 28304c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 28314c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 28324c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 2833d1e9a80fSBarry Smith ierr = MatFDColoringApply(Bfd,matfdcoloring,X,snes);CHKERRQ(ierr); 28344c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 28354c30e9fbSJed Brown 2836ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr); 28374c30e9fbSJed Brown if (flag_draw || flag_contour) { 28389e5d0892SLisandro Dalcin ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 28394c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 28400298fd71SBarry Smith } else vdraw = NULL; 28414c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 284294ab13aaSBarry Smith if (flag_display) {ierr = MatView(B,vstdout);CHKERRQ(ierr);} 284394ab13aaSBarry Smith if (vdraw) {ierr = MatView(B,vdraw);CHKERRQ(ierr);} 28444c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 28456719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 28464c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 284794ab13aaSBarry Smith ierr = MatAYPX(Bfd,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 28484c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 28496719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 28504c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 285157622a8eSBarry 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); 28526719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 28534c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 28544c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 28554c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 28564c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 28574c30e9fbSJed Brown } 28584c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 28596719d8e4SJed Brown 28606719d8e4SJed Brown if (flag_threshold) { 28616719d8e4SJed Brown PetscInt bs,rstart,rend,i; 286294ab13aaSBarry Smith ierr = MatGetBlockSize(B,&bs);CHKERRQ(ierr); 286394ab13aaSBarry Smith ierr = MatGetOwnershipRange(B,&rstart,&rend);CHKERRQ(ierr); 28646719d8e4SJed Brown for (i=rstart; i<rend; i++) { 28656719d8e4SJed Brown const PetscScalar *ba,*ca; 28666719d8e4SJed Brown const PetscInt *bj,*cj; 28676719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 28686719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 286994ab13aaSBarry Smith ierr = MatGetRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr); 28706719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 287194ab13aaSBarry Smith if (bn != cn) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 28726719d8e4SJed Brown for (j=0; j<bn; j++) { 28736719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 28746719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 28756719d8e4SJed Brown maxentrycol = bj[j]; 28766719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 28776719d8e4SJed Brown } 28786719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 28796719d8e4SJed Brown maxdiffcol = bj[j]; 28806719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 28816719d8e4SJed Brown } 28826719d8e4SJed Brown if (rdiff > maxrdiff) { 28836719d8e4SJed Brown maxrdiffcol = bj[j]; 28846719d8e4SJed Brown maxrdiff = rdiff; 28856719d8e4SJed Brown } 28866719d8e4SJed Brown } 28876719d8e4SJed Brown if (maxrdiff > 1) { 288857622a8eSBarry 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); 28896719d8e4SJed Brown for (j=0; j<bn; j++) { 28906719d8e4SJed Brown PetscReal rdiff; 28916719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 28926719d8e4SJed Brown if (rdiff > 1) { 289357622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(vstdout," (%D,%g:%g)",bj[j],(double)PetscRealPart(ba[j]),(double)PetscRealPart(ca[j]));CHKERRQ(ierr); 28946719d8e4SJed Brown } 28956719d8e4SJed Brown } 28966719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 28976719d8e4SJed Brown } 289894ab13aaSBarry Smith ierr = MatRestoreRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr); 28996719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 29006719d8e4SJed Brown } 29016719d8e4SJed Brown } 29024c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 29034c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 29044c30e9fbSJed Brown } 29054c30e9fbSJed Brown } 29063a40ed3dSBarry Smith PetscFunctionReturn(0); 29079b94acceSBarry Smith } 29089b94acceSBarry Smith 2909bf388a1fSBarry Smith /*MC 2910411c0326SBarry Smith SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES 2911bf388a1fSBarry Smith 2912bf388a1fSBarry Smith Synopsis: 2913411c0326SBarry Smith #include "petscsnes.h" 2914411c0326SBarry Smith PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx); 2915bf388a1fSBarry Smith 29161843f636SBarry Smith Collective on snes 29171843f636SBarry Smith 29181843f636SBarry Smith Input Parameters: 29191843f636SBarry Smith + x - input vector, the Jacobian is to be computed at this value 2920bf388a1fSBarry Smith - ctx - [optional] user-defined Jacobian context 2921bf388a1fSBarry Smith 29221843f636SBarry Smith Output Parameters: 29231843f636SBarry Smith + Amat - the matrix that defines the (approximate) Jacobian 29241843f636SBarry Smith - Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 29251843f636SBarry Smith 2926878cb397SSatish Balay Level: intermediate 2927878cb397SSatish Balay 2928bf388a1fSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction(), SNESSetJacobian(), SNESGetJacobian() 2929bf388a1fSBarry Smith M*/ 2930bf388a1fSBarry Smith 29319b94acceSBarry Smith /*@C 29329b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2933044dda88SLois Curfman McInnes location to store the matrix. 29349b94acceSBarry Smith 2935d083f849SBarry Smith Logically Collective on SNES 2936c7afd0dbSLois Curfman McInnes 29379b94acceSBarry Smith Input Parameters: 2938c7afd0dbSLois Curfman McInnes + snes - the SNES context 2939e5d3d808SBarry Smith . Amat - the matrix that defines the (approximate) Jacobian 2940e5d3d808SBarry Smith . Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 2941411c0326SBarry Smith . J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details 2942c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 29430298fd71SBarry Smith Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value) 29449b94acceSBarry Smith 29459b94acceSBarry Smith Notes: 2946e5d3d808SBarry Smith If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on 294716913363SBarry Smith each matrix. 294816913363SBarry Smith 2949895c21f2SBarry Smith If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null 2950895c21f2SBarry Smith space to Amat and the KSP solvers will automatically use that null space as needed during the solution process. 2951895c21f2SBarry Smith 29528d359177SBarry Smith If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument 2953a8a26c1eSJed Brown must be a MatFDColoring. 2954a8a26c1eSJed Brown 2955c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2956c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2957c3cc8fd1SJed Brown 295836851e7fSLois Curfman McInnes Level: beginner 295936851e7fSLois Curfman McInnes 2960411c0326SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESComputeJacobianDefaultColor(), MatStructure, J, 2961411c0326SBarry Smith SNESSetPicard(), SNESJacobianFunction 29629b94acceSBarry Smith @*/ 2963d1e9a80fSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx) 29649b94acceSBarry Smith { 2965dfbe8321SBarry Smith PetscErrorCode ierr; 29666cab3a1bSJed Brown DM dm; 29673a7fca6bSBarry Smith 29683a40ed3dSBarry Smith PetscFunctionBegin; 29690700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2970e5d3d808SBarry Smith if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 2971e5d3d808SBarry Smith if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 2972e5d3d808SBarry Smith if (Amat) PetscCheckSameComm(snes,1,Amat,2); 2973e5d3d808SBarry Smith if (Pmat) PetscCheckSameComm(snes,1,Pmat,3); 29746cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2975f8b49ee9SBarry Smith ierr = DMSNESSetJacobian(dm,J,ctx);CHKERRQ(ierr); 2976e5d3d808SBarry Smith if (Amat) { 2977e5d3d808SBarry Smith ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 29786bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 2979f5af7f23SKarl Rupp 2980e5d3d808SBarry Smith snes->jacobian = Amat; 29813a7fca6bSBarry Smith } 2982e5d3d808SBarry Smith if (Pmat) { 2983e5d3d808SBarry Smith ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr); 29846bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2985f5af7f23SKarl Rupp 2986e5d3d808SBarry Smith snes->jacobian_pre = Pmat; 29873a7fca6bSBarry Smith } 29883a40ed3dSBarry Smith PetscFunctionReturn(0); 29899b94acceSBarry Smith } 299062fef451SLois Curfman McInnes 2991c2aafc4cSSatish Balay /*@C 2992b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2993b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2994b4fd4287SBarry Smith 2995c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2996c7afd0dbSLois Curfman McInnes 2997b4fd4287SBarry Smith Input Parameter: 2998b4fd4287SBarry Smith . snes - the nonlinear solver context 2999b4fd4287SBarry Smith 3000b4fd4287SBarry Smith Output Parameters: 3001e5d3d808SBarry Smith + Amat - location to stash (approximate) Jacobian matrix (or NULL) 3002e5d3d808SBarry Smith . Pmat - location to stash matrix used to compute the preconditioner (or NULL) 3003411c0326SBarry Smith . J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence 30040298fd71SBarry Smith - ctx - location to stash Jacobian ctx (or NULL) 3005fee21e36SBarry Smith 300636851e7fSLois Curfman McInnes Level: advanced 300736851e7fSLois Curfman McInnes 3008411c0326SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian(), SNESJacobianFunction, SNESGetFunction() 3009b4fd4287SBarry Smith @*/ 3010d1e9a80fSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx) 3011b4fd4287SBarry Smith { 30126cab3a1bSJed Brown PetscErrorCode ierr; 30136cab3a1bSJed Brown DM dm; 3014942e3340SBarry Smith DMSNES sdm; 30156cab3a1bSJed Brown 30163a40ed3dSBarry Smith PetscFunctionBegin; 30170700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3018e5d3d808SBarry Smith if (Amat) *Amat = snes->jacobian; 3019e5d3d808SBarry Smith if (Pmat) *Pmat = snes->jacobian_pre; 30206cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3021942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 3022f8b49ee9SBarry Smith if (J) *J = sdm->ops->computejacobian; 30236cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 30243a40ed3dSBarry Smith PetscFunctionReturn(0); 3025b4fd4287SBarry Smith } 3026b4fd4287SBarry Smith 302758b371f3SBarry Smith static PetscErrorCode SNESSetDefaultComputeJacobian(SNES snes) 302858b371f3SBarry Smith { 302958b371f3SBarry Smith PetscErrorCode ierr; 303058b371f3SBarry Smith DM dm; 303158b371f3SBarry Smith DMSNES sdm; 303258b371f3SBarry Smith 303358b371f3SBarry Smith PetscFunctionBegin; 303458b371f3SBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 303558b371f3SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 303658b371f3SBarry Smith if (!sdm->ops->computejacobian && snes->jacobian_pre) { 303758b371f3SBarry Smith DM dm; 303858b371f3SBarry Smith PetscBool isdense,ismf; 303958b371f3SBarry Smith 304058b371f3SBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 304158b371f3SBarry Smith ierr = PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre,&isdense,MATSEQDENSE,MATMPIDENSE,MATDENSE,NULL);CHKERRQ(ierr); 304258b371f3SBarry Smith ierr = PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre,&ismf,MATMFFD,MATSHELL,NULL);CHKERRQ(ierr); 304358b371f3SBarry Smith if (isdense) { 304458b371f3SBarry Smith ierr = DMSNESSetJacobian(dm,SNESComputeJacobianDefault,NULL);CHKERRQ(ierr); 304558b371f3SBarry Smith } else if (!ismf) { 304658b371f3SBarry Smith ierr = DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr); 304758b371f3SBarry Smith } 304858b371f3SBarry Smith } 304958b371f3SBarry Smith PetscFunctionReturn(0); 305058b371f3SBarry Smith } 305158b371f3SBarry Smith 30529b94acceSBarry Smith /*@ 30539b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 3054272ac6f2SLois Curfman McInnes of a nonlinear solver. 30559b94acceSBarry Smith 3056fee21e36SBarry Smith Collective on SNES 3057fee21e36SBarry Smith 3058c7afd0dbSLois Curfman McInnes Input Parameters: 305970e92668SMatthew Knepley . snes - the SNES context 3060c7afd0dbSLois Curfman McInnes 3061272ac6f2SLois Curfman McInnes Notes: 3062272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 3063272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 3064272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 3065272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 3066272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 3067272ac6f2SLois Curfman McInnes 306836851e7fSLois Curfman McInnes Level: advanced 306936851e7fSLois Curfman McInnes 30709b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 30719b94acceSBarry Smith @*/ 30727087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 30739b94acceSBarry Smith { 3074dfbe8321SBarry Smith PetscErrorCode ierr; 30756cab3a1bSJed Brown DM dm; 3076942e3340SBarry Smith DMSNES sdm; 3077c35f09e5SBarry Smith SNESLineSearch linesearch, pclinesearch; 30786e2a1849SPeter Brune void *lsprectx,*lspostctx; 30796b2b7091SBarry Smith PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*); 30806b2b7091SBarry Smith PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*); 30816e2a1849SPeter Brune PetscErrorCode (*func)(SNES,Vec,Vec,void*); 30826e2a1849SPeter Brune Vec f,fpc; 30836e2a1849SPeter Brune void *funcctx; 3084d1e9a80fSBarry Smith PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*); 30851eb13d49SPeter Brune void *jacctx,*appctx; 308632b97717SPeter Brune Mat j,jpre; 30873a40ed3dSBarry Smith 30883a40ed3dSBarry Smith PetscFunctionBegin; 30890700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 30904dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 3091e3ed9ee7SBarry Smith ierr = PetscLogEventBegin(SNES_Setup,snes,0,0,0);CHKERRQ(ierr); 30929b94acceSBarry Smith 30937adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 309404d7464bSBarry Smith ierr = SNESSetType(snes,SNESNEWTONLS);CHKERRQ(ierr); 309585385478SLisandro Dalcin } 309685385478SLisandro Dalcin 30970298fd71SBarry Smith ierr = SNESGetFunction(snes,&snes->vec_func,NULL,NULL);CHKERRQ(ierr); 309858c9b817SLisandro Dalcin 30996cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3100942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 3101ce94432eSBarry Smith if (!sdm->ops->computefunction) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object"); 310258b371f3SBarry Smith ierr = SNESSetDefaultComputeJacobian(snes);CHKERRQ(ierr); 310358b371f3SBarry Smith 31046cab3a1bSJed Brown if (!snes->vec_func) { 31056cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 3106214df951SJed Brown } 3107efd51863SBarry Smith 310822d28d08SBarry Smith if (!snes->ksp) { 310922d28d08SBarry Smith ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr); 311022d28d08SBarry Smith } 3111b710008aSBarry Smith 3112d8d34be6SBarry Smith if (snes->linesearch) { 31137601faf0SJed Brown ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 3114ed07d7d7SPeter Brune ierr = SNESLineSearchSetFunction(snes->linesearch,SNESComputeFunction);CHKERRQ(ierr); 3115d8d34be6SBarry Smith } 31169e764e56SPeter Brune 3117efd4aadfSBarry Smith if (snes->npc && (snes->npcside== PC_LEFT)) { 3118172a4300SPeter Brune snes->mf = PETSC_TRUE; 3119172a4300SPeter Brune snes->mf_operator = PETSC_FALSE; 3120172a4300SPeter Brune } 3121d8f46077SPeter Brune 3122efd4aadfSBarry Smith if (snes->npc) { 31236e2a1849SPeter Brune /* copy the DM over */ 31246e2a1849SPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3125efd4aadfSBarry Smith ierr = SNESSetDM(snes->npc,dm);CHKERRQ(ierr); 31266e2a1849SPeter Brune 31276e2a1849SPeter Brune ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr); 31286e2a1849SPeter Brune ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr); 3129efd4aadfSBarry Smith ierr = SNESSetFunction(snes->npc,fpc,func,funcctx);CHKERRQ(ierr); 313032b97717SPeter Brune ierr = SNESGetJacobian(snes,&j,&jpre,&jac,&jacctx);CHKERRQ(ierr); 3131efd4aadfSBarry Smith ierr = SNESSetJacobian(snes->npc,j,jpre,jac,jacctx);CHKERRQ(ierr); 31321eb13d49SPeter Brune ierr = SNESGetApplicationContext(snes,&appctx);CHKERRQ(ierr); 3133efd4aadfSBarry Smith ierr = SNESSetApplicationContext(snes->npc,appctx);CHKERRQ(ierr); 31346e2a1849SPeter Brune ierr = VecDestroy(&fpc);CHKERRQ(ierr); 31356e2a1849SPeter Brune 31366e2a1849SPeter Brune /* copy the function pointers over */ 3137efd4aadfSBarry Smith ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr); 31386e2a1849SPeter Brune 31396e2a1849SPeter Brune /* default to 1 iteration */ 3140efd4aadfSBarry Smith ierr = SNESSetTolerances(snes->npc,0.0,0.0,0.0,1,snes->npc->max_funcs);CHKERRQ(ierr); 3141efd4aadfSBarry Smith if (snes->npcside==PC_RIGHT) { 3142efd4aadfSBarry Smith ierr = SNESSetNormSchedule(snes->npc,SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); 3143a9936a0cSPeter Brune } else { 3144efd4aadfSBarry Smith ierr = SNESSetNormSchedule(snes->npc,SNES_NORM_NONE);CHKERRQ(ierr); 3145a9936a0cSPeter Brune } 3146efd4aadfSBarry Smith ierr = SNESSetFromOptions(snes->npc);CHKERRQ(ierr); 31476e2a1849SPeter Brune 31486e2a1849SPeter Brune /* copy the line search context over */ 3149d8d34be6SBarry Smith if (snes->linesearch && snes->npc->linesearch) { 31507601faf0SJed Brown ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); 3151efd4aadfSBarry Smith ierr = SNESGetLineSearch(snes->npc,&pclinesearch);CHKERRQ(ierr); 31526b2b7091SBarry Smith ierr = SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx);CHKERRQ(ierr); 31536b2b7091SBarry Smith ierr = SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx);CHKERRQ(ierr); 31546b2b7091SBarry Smith ierr = SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx);CHKERRQ(ierr); 31556b2b7091SBarry Smith ierr = SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx);CHKERRQ(ierr); 31566e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr); 31576e2a1849SPeter Brune } 3158d8d34be6SBarry Smith } 315932b97717SPeter Brune if (snes->mf) { 316032b97717SPeter Brune ierr = SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);CHKERRQ(ierr); 316132b97717SPeter Brune } 316232b97717SPeter Brune if (snes->ops->usercompute && !snes->user) { 316332b97717SPeter Brune ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 316432b97717SPeter Brune } 31656e2a1849SPeter Brune 316637ec4e1aSPeter Brune snes->jac_iter = 0; 316737ec4e1aSPeter Brune snes->pre_iter = 0; 316837ec4e1aSPeter Brune 3169410397dcSLisandro Dalcin if (snes->ops->setup) { 3170410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 3171410397dcSLisandro Dalcin } 317258c9b817SLisandro Dalcin 317358b371f3SBarry Smith ierr = SNESSetDefaultComputeJacobian(snes);CHKERRQ(ierr); 317458b371f3SBarry Smith 3175efd4aadfSBarry Smith if (snes->npc && (snes->npcside== PC_LEFT)) { 31766c67d002SPeter Brune if (snes->functype == SNES_FUNCTION_PRECONDITIONED) { 3177d8d34be6SBarry Smith if (snes->linesearch){ 317855d4788fSPeter Brune ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); 3179be95d8f1SBarry Smith ierr = SNESLineSearchSetFunction(linesearch,SNESComputeFunctionDefaultNPC);CHKERRQ(ierr); 31806c67d002SPeter Brune } 31816c67d002SPeter Brune } 3182d8d34be6SBarry Smith } 3183e3ed9ee7SBarry Smith ierr = PetscLogEventEnd(SNES_Setup,snes,0,0,0);CHKERRQ(ierr); 31847aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 31853a40ed3dSBarry Smith PetscFunctionReturn(0); 31869b94acceSBarry Smith } 31879b94acceSBarry Smith 318837596af1SLisandro Dalcin /*@ 318937596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 319037596af1SLisandro Dalcin 319137596af1SLisandro Dalcin Collective on SNES 319237596af1SLisandro Dalcin 319337596af1SLisandro Dalcin Input Parameter: 319437596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 319537596af1SLisandro Dalcin 3196d25893d9SBarry Smith Level: intermediate 3197d25893d9SBarry Smith 319895452b02SPatrick Sanan Notes: 319995452b02SPatrick Sanan Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 320037596af1SLisandro Dalcin 320137596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 320237596af1SLisandro Dalcin @*/ 320337596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 320437596af1SLisandro Dalcin { 320537596af1SLisandro Dalcin PetscErrorCode ierr; 320637596af1SLisandro Dalcin 320737596af1SLisandro Dalcin PetscFunctionBegin; 320837596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3209d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 3210d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 32110298fd71SBarry Smith snes->user = NULL; 3212d25893d9SBarry Smith } 3213efd4aadfSBarry Smith if (snes->npc) { 3214efd4aadfSBarry Smith ierr = SNESReset(snes->npc);CHKERRQ(ierr); 32158a23116dSBarry Smith } 32168a23116dSBarry Smith 321737596af1SLisandro Dalcin if (snes->ops->reset) { 321837596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 321937596af1SLisandro Dalcin } 32209e764e56SPeter Brune if (snes->ksp) { 32219e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 32229e764e56SPeter Brune } 32239e764e56SPeter Brune 32249e764e56SPeter Brune if (snes->linesearch) { 3225f1c6b773SPeter Brune ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 32269e764e56SPeter Brune } 32279e764e56SPeter Brune 32286bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 32296bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 32306bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 32316bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 32326bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 32336bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 3234c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 3235c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 3236f5af7f23SKarl Rupp 323740fdac6aSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 323840fdac6aSLawrence Mitchell 323937596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 324037596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 324137596af1SLisandro Dalcin PetscFunctionReturn(0); 324237596af1SLisandro Dalcin } 324337596af1SLisandro Dalcin 324452baeb72SSatish Balay /*@ 32459b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 32469b94acceSBarry Smith with SNESCreate(). 32479b94acceSBarry Smith 3248c7afd0dbSLois Curfman McInnes Collective on SNES 3249c7afd0dbSLois Curfman McInnes 32509b94acceSBarry Smith Input Parameter: 32519b94acceSBarry Smith . snes - the SNES context 32529b94acceSBarry Smith 325336851e7fSLois Curfman McInnes Level: beginner 325436851e7fSLois Curfman McInnes 325563a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 32569b94acceSBarry Smith @*/ 32576bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 32589b94acceSBarry Smith { 32596849ba73SBarry Smith PetscErrorCode ierr; 32603a40ed3dSBarry Smith 32613a40ed3dSBarry Smith PetscFunctionBegin; 32626bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 32636bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 32649e5d0892SLisandro Dalcin if (--((PetscObject)(*snes))->refct > 0) {*snes = NULL; PetscFunctionReturn(0);} 3265d4bb536fSBarry Smith 32666bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 3267efd4aadfSBarry Smith ierr = SNESDestroy(&(*snes)->npc);CHKERRQ(ierr); 32686b8b9a38SLisandro Dalcin 3269e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 3270e04113cfSBarry Smith ierr = PetscObjectSAWsViewOff((PetscObject)*snes);CHKERRQ(ierr); 32716bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 32726d4c513bSLisandro Dalcin 327333124788SMatthew G. Knepley if ((*snes)->dm) {ierr = DMCoarsenHookRemove((*snes)->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,*snes);CHKERRQ(ierr);} 32746bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 32756bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 3276f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 32776b8b9a38SLisandro Dalcin 32786bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 32796bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 32806bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 32816b8b9a38SLisandro Dalcin } 3282071fcb05SBarry Smith if ((*snes)->conv_hist_alloc) { 3283071fcb05SBarry Smith ierr = PetscFree2((*snes)->conv_hist,(*snes)->conv_hist_its);CHKERRQ(ierr); 328458c9b817SLisandro Dalcin } 32856bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 3286a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 32873a40ed3dSBarry Smith PetscFunctionReturn(0); 32889b94acceSBarry Smith } 32899b94acceSBarry Smith 32909b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 32919b94acceSBarry Smith 3292a8054027SBarry Smith /*@ 3293a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 3294a8054027SBarry Smith 32953f9fe445SBarry Smith Logically Collective on SNES 3296a8054027SBarry Smith 3297a8054027SBarry Smith Input Parameters: 3298a8054027SBarry Smith + snes - the SNES context 3299a8054027SBarry 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 33003b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3301a8054027SBarry Smith 3302a8054027SBarry Smith Options Database Keys: 33033d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 33043d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 33053d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 33063d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3307a8054027SBarry Smith 3308a8054027SBarry Smith Notes: 3309a8054027SBarry Smith The default is 1 33103d5a8a6aSBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or SNESSetLagPreconditionerPersists() was called 3311a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 3312a8054027SBarry Smith 3313a8054027SBarry Smith Level: intermediate 3314a8054027SBarry Smith 33153d5a8a6aSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetLagPreconditionerPersists(), 33163d5a8a6aSBarry Smith SNESSetLagJacobianPersists() 3317a8054027SBarry Smith 3318a8054027SBarry Smith @*/ 33197087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 3320a8054027SBarry Smith { 3321a8054027SBarry Smith PetscFunctionBegin; 33220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3323e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 3324e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 3325c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 3326a8054027SBarry Smith snes->lagpreconditioner = lag; 3327a8054027SBarry Smith PetscFunctionReturn(0); 3328a8054027SBarry Smith } 3329a8054027SBarry Smith 3330efd51863SBarry Smith /*@ 3331efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 3332efd51863SBarry Smith 3333efd51863SBarry Smith Logically Collective on SNES 3334efd51863SBarry Smith 3335efd51863SBarry Smith Input Parameters: 3336efd51863SBarry Smith + snes - the SNES context 3337efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 3338efd51863SBarry Smith 3339efd51863SBarry Smith Options Database Keys: 3340efd51863SBarry Smith . -snes_grid_sequence <steps> 3341efd51863SBarry Smith 3342efd51863SBarry Smith Level: intermediate 3343efd51863SBarry Smith 3344c0df2a02SJed Brown Notes: 3345c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 3346c0df2a02SJed Brown 3347fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetGridSequence() 3348efd51863SBarry Smith 3349efd51863SBarry Smith @*/ 3350efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 3351efd51863SBarry Smith { 3352efd51863SBarry Smith PetscFunctionBegin; 3353efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3354efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 3355efd51863SBarry Smith snes->gridsequence = steps; 3356efd51863SBarry Smith PetscFunctionReturn(0); 3357efd51863SBarry Smith } 3358efd51863SBarry Smith 3359fa19ca70SBarry Smith /*@ 3360fa19ca70SBarry Smith SNESGetGridSequence - gets the number of steps of grid sequencing that SNES does 3361fa19ca70SBarry Smith 3362fa19ca70SBarry Smith Logically Collective on SNES 3363fa19ca70SBarry Smith 3364fa19ca70SBarry Smith Input Parameter: 3365fa19ca70SBarry Smith . snes - the SNES context 3366fa19ca70SBarry Smith 3367fa19ca70SBarry Smith Output Parameter: 3368fa19ca70SBarry Smith . steps - the number of refinements to do, defaults to 0 3369fa19ca70SBarry Smith 3370fa19ca70SBarry Smith Options Database Keys: 3371fa19ca70SBarry Smith . -snes_grid_sequence <steps> 3372fa19ca70SBarry Smith 3373fa19ca70SBarry Smith Level: intermediate 3374fa19ca70SBarry Smith 3375fa19ca70SBarry Smith Notes: 3376fa19ca70SBarry Smith Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 3377fa19ca70SBarry Smith 3378fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetGridSequence() 3379fa19ca70SBarry Smith 3380fa19ca70SBarry Smith @*/ 3381fa19ca70SBarry Smith PetscErrorCode SNESGetGridSequence(SNES snes,PetscInt *steps) 3382fa19ca70SBarry Smith { 3383fa19ca70SBarry Smith PetscFunctionBegin; 3384fa19ca70SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3385fa19ca70SBarry Smith *steps = snes->gridsequence; 3386fa19ca70SBarry Smith PetscFunctionReturn(0); 3387fa19ca70SBarry Smith } 3388fa19ca70SBarry Smith 3389a8054027SBarry Smith /*@ 3390a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 3391a8054027SBarry Smith 33923f9fe445SBarry Smith Not Collective 3393a8054027SBarry Smith 3394a8054027SBarry Smith Input Parameter: 3395a8054027SBarry Smith . snes - the SNES context 3396a8054027SBarry Smith 3397a8054027SBarry Smith Output Parameter: 3398a8054027SBarry 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 33993b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3400a8054027SBarry Smith 3401a8054027SBarry Smith Options Database Keys: 34023d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 34033d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 34043d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 34053d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3406a8054027SBarry Smith 3407a8054027SBarry Smith Notes: 3408a8054027SBarry Smith The default is 1 3409a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3410a8054027SBarry Smith 3411a8054027SBarry Smith Level: intermediate 3412a8054027SBarry Smith 34133d5a8a6aSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner(), SNESSetLagJacobianPersists(), SNESSetLagPreconditionerPersists() 3414a8054027SBarry Smith 3415a8054027SBarry Smith @*/ 34167087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 3417a8054027SBarry Smith { 3418a8054027SBarry Smith PetscFunctionBegin; 34190700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3420a8054027SBarry Smith *lag = snes->lagpreconditioner; 3421a8054027SBarry Smith PetscFunctionReturn(0); 3422a8054027SBarry Smith } 3423a8054027SBarry Smith 3424e35cf81dSBarry Smith /*@ 3425e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 3426e35cf81dSBarry Smith often the preconditioner is rebuilt. 3427e35cf81dSBarry Smith 34283f9fe445SBarry Smith Logically Collective on SNES 3429e35cf81dSBarry Smith 3430e35cf81dSBarry Smith Input Parameters: 3431e35cf81dSBarry Smith + snes - the SNES context 3432e35cf81dSBarry 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 3433fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 3434e35cf81dSBarry Smith 3435e35cf81dSBarry Smith Options Database Keys: 34363d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 34373d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 34383d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 34393d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag. 3440e35cf81dSBarry Smith 3441e35cf81dSBarry Smith Notes: 3442e35cf81dSBarry Smith The default is 1 3443e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3444fe3ffe1eSBarry 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 3445fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 3446e35cf81dSBarry Smith 3447e35cf81dSBarry Smith Level: intermediate 3448e35cf81dSBarry Smith 34493d5a8a6aSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobianPersists(), SNESSetLagPreconditionerPersists() 3450e35cf81dSBarry Smith 3451e35cf81dSBarry Smith @*/ 34527087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 3453e35cf81dSBarry Smith { 3454e35cf81dSBarry Smith PetscFunctionBegin; 34550700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3456e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 3457e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 3458c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 3459e35cf81dSBarry Smith snes->lagjacobian = lag; 3460e35cf81dSBarry Smith PetscFunctionReturn(0); 3461e35cf81dSBarry Smith } 3462e35cf81dSBarry Smith 3463e35cf81dSBarry Smith /*@ 3464e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 3465e35cf81dSBarry Smith 34663f9fe445SBarry Smith Not Collective 3467e35cf81dSBarry Smith 3468e35cf81dSBarry Smith Input Parameter: 3469e35cf81dSBarry Smith . snes - the SNES context 3470e35cf81dSBarry Smith 3471e35cf81dSBarry Smith Output Parameter: 3472e35cf81dSBarry 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 3473e35cf81dSBarry Smith the Jacobian is built etc. 3474e35cf81dSBarry Smith 3475e35cf81dSBarry Smith Notes: 3476e35cf81dSBarry Smith The default is 1 34773d5a8a6aSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or SNESSetLagJacobianPersists() was called. 3478e35cf81dSBarry Smith 3479e35cf81dSBarry Smith Level: intermediate 3480e35cf81dSBarry Smith 34813d5a8a6aSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner(), SNESSetLagJacobianPersists(), SNESSetLagPreconditionerPersists() 3482e35cf81dSBarry Smith 3483e35cf81dSBarry Smith @*/ 34847087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 3485e35cf81dSBarry Smith { 3486e35cf81dSBarry Smith PetscFunctionBegin; 34870700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3488e35cf81dSBarry Smith *lag = snes->lagjacobian; 3489e35cf81dSBarry Smith PetscFunctionReturn(0); 3490e35cf81dSBarry Smith } 3491e35cf81dSBarry Smith 349237ec4e1aSPeter Brune /*@ 349337ec4e1aSPeter Brune SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves 349437ec4e1aSPeter Brune 349537ec4e1aSPeter Brune Logically collective on SNES 349637ec4e1aSPeter Brune 349737ec4e1aSPeter Brune Input Parameter: 349837ec4e1aSPeter Brune + snes - the SNES context 34999d7e2deaSPeter Brune - flg - jacobian lagging persists if true 350037ec4e1aSPeter Brune 350137ec4e1aSPeter Brune Options Database Keys: 35023d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 35033d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 35043d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 35053d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 35063d5a8a6aSBarry Smith 350737ec4e1aSPeter Brune 350895452b02SPatrick Sanan Notes: 350995452b02SPatrick Sanan This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by 351037ec4e1aSPeter Brune several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several 351137ec4e1aSPeter Brune timesteps may present huge efficiency gains. 351237ec4e1aSPeter Brune 351337ec4e1aSPeter Brune Level: developer 351437ec4e1aSPeter Brune 35153d5a8a6aSBarry Smith .seealso: SNESSetLagPreconditionerPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC(), SNESSetLagJacobianPersists() 351637ec4e1aSPeter Brune 351737ec4e1aSPeter Brune @*/ 351837ec4e1aSPeter Brune PetscErrorCode SNESSetLagJacobianPersists(SNES snes,PetscBool flg) 351937ec4e1aSPeter Brune { 352037ec4e1aSPeter Brune PetscFunctionBegin; 352137ec4e1aSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 352237ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes,flg,2); 352337ec4e1aSPeter Brune snes->lagjac_persist = flg; 352437ec4e1aSPeter Brune PetscFunctionReturn(0); 352537ec4e1aSPeter Brune } 352637ec4e1aSPeter Brune 352737ec4e1aSPeter Brune /*@ 352837ec4e1aSPeter Brune SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple solves 352937ec4e1aSPeter Brune 353037ec4e1aSPeter Brune Logically Collective on SNES 353137ec4e1aSPeter Brune 353237ec4e1aSPeter Brune Input Parameter: 353337ec4e1aSPeter Brune + snes - the SNES context 35349d7e2deaSPeter Brune - flg - preconditioner lagging persists if true 353537ec4e1aSPeter Brune 353637ec4e1aSPeter Brune Options Database Keys: 35373d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 35383d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 35393d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 35403d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 354137ec4e1aSPeter Brune 354295452b02SPatrick Sanan Notes: 354395452b02SPatrick Sanan This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale 354437ec4e1aSPeter Brune by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over 354537ec4e1aSPeter Brune several timesteps may present huge efficiency gains. 354637ec4e1aSPeter Brune 354737ec4e1aSPeter Brune Level: developer 354837ec4e1aSPeter Brune 35493d5a8a6aSBarry Smith .seealso: SNESSetLagJacobianPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC(), SNESSetLagPreconditioner() 355037ec4e1aSPeter Brune 355137ec4e1aSPeter Brune @*/ 355237ec4e1aSPeter Brune PetscErrorCode SNESSetLagPreconditionerPersists(SNES snes,PetscBool flg) 355337ec4e1aSPeter Brune { 355437ec4e1aSPeter Brune PetscFunctionBegin; 355537ec4e1aSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 355637ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes,flg,2); 355737ec4e1aSPeter Brune snes->lagpre_persist = flg; 355837ec4e1aSPeter Brune PetscFunctionReturn(0); 355937ec4e1aSPeter Brune } 356037ec4e1aSPeter Brune 35619b94acceSBarry Smith /*@ 3562be5caee7SBarry Smith SNESSetForceIteration - force SNESSolve() to take at least one iteration regardless of the initial residual norm 3563be5caee7SBarry Smith 3564be5caee7SBarry Smith Logically Collective on SNES 3565be5caee7SBarry Smith 3566be5caee7SBarry Smith Input Parameters: 3567be5caee7SBarry Smith + snes - the SNES context 3568be5caee7SBarry Smith - force - PETSC_TRUE require at least one iteration 3569be5caee7SBarry Smith 3570be5caee7SBarry Smith Options Database Keys: 3571be5caee7SBarry Smith . -snes_force_iteration <force> - Sets forcing an iteration 3572be5caee7SBarry Smith 3573be5caee7SBarry Smith Notes: 3574be5caee7SBarry Smith This is used sometimes with TS to prevent TS from detecting a false steady state solution 3575be5caee7SBarry Smith 3576be5caee7SBarry Smith Level: intermediate 3577be5caee7SBarry Smith 3578be5caee7SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance() 3579be5caee7SBarry Smith @*/ 3580be5caee7SBarry Smith PetscErrorCode SNESSetForceIteration(SNES snes,PetscBool force) 3581be5caee7SBarry Smith { 3582be5caee7SBarry Smith PetscFunctionBegin; 3583be5caee7SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3584be5caee7SBarry Smith snes->forceiteration = force; 3585be5caee7SBarry Smith PetscFunctionReturn(0); 3586be5caee7SBarry Smith } 3587be5caee7SBarry Smith 358885216dc7SFande Kong /*@ 358985216dc7SFande Kong SNESGetForceIteration - Whether or not to force SNESSolve() take at least one iteration regardless of the initial residual norm 359085216dc7SFande Kong 359185216dc7SFande Kong Logically Collective on SNES 359285216dc7SFande Kong 359385216dc7SFande Kong Input Parameters: 359485216dc7SFande Kong . snes - the SNES context 359585216dc7SFande Kong 359685216dc7SFande Kong Output Parameter: 359785216dc7SFande Kong . force - PETSC_TRUE requires at least one iteration. 359885216dc7SFande Kong 359906dd6b0eSSatish Balay Level: intermediate 360006dd6b0eSSatish Balay 360185216dc7SFande Kong .seealso: SNESSetForceIteration(), SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance() 360285216dc7SFande Kong @*/ 360385216dc7SFande Kong PetscErrorCode SNESGetForceIteration(SNES snes,PetscBool *force) 360485216dc7SFande Kong { 360585216dc7SFande Kong PetscFunctionBegin; 360685216dc7SFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 360785216dc7SFande Kong *force = snes->forceiteration; 360885216dc7SFande Kong PetscFunctionReturn(0); 360985216dc7SFande Kong } 3610be5caee7SBarry Smith 3611be5caee7SBarry Smith /*@ 3612d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 36139b94acceSBarry Smith 36143f9fe445SBarry Smith Logically Collective on SNES 3615c7afd0dbSLois Curfman McInnes 36169b94acceSBarry Smith Input Parameters: 3617c7afd0dbSLois Curfman McInnes + snes - the SNES context 361870441072SBarry Smith . abstol - absolute convergence tolerance 361933174efeSLois Curfman McInnes . rtol - relative convergence tolerance 36205358d0d4SBarry Smith . stol - convergence tolerance in terms of the norm of the change in the solution between steps, || delta x || < stol*|| x || 362133174efeSLois Curfman McInnes . maxit - maximum number of iterations 3622e71169deSBarry Smith - maxf - maximum number of function evaluations (-1 indicates no limit) 3623fee21e36SBarry Smith 362433174efeSLois Curfman McInnes Options Database Keys: 362570441072SBarry Smith + -snes_atol <abstol> - Sets abstol 3626c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 3627c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 3628c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 3629c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 36309b94acceSBarry Smith 3631d7a720efSLois Curfman McInnes Notes: 36329b94acceSBarry Smith The default maximum number of iterations is 50. 36339b94acceSBarry Smith The default maximum number of function evaluations is 1000. 36349b94acceSBarry Smith 363536851e7fSLois Curfman McInnes Level: intermediate 363636851e7fSLois Curfman McInnes 3637be5caee7SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance(), SNESSetForceIteration() 36389b94acceSBarry Smith @*/ 36397087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 36409b94acceSBarry Smith { 36413a40ed3dSBarry Smith PetscFunctionBegin; 36420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3643c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 3644c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 3645c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 3646c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 3647c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 3648c5eb9154SBarry Smith 3649ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 365057622a8eSBarry Smith if (abstol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g must be non-negative",(double)abstol); 3651ab54825eSJed Brown snes->abstol = abstol; 3652ab54825eSJed Brown } 3653ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 365457622a8eSBarry 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); 3655ab54825eSJed Brown snes->rtol = rtol; 3656ab54825eSJed Brown } 3657ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 365857622a8eSBarry Smith if (stol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %g must be non-negative",(double)stol); 3659c60f73f4SPeter Brune snes->stol = stol; 3660ab54825eSJed Brown } 3661ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 3662ce94432eSBarry Smith if (maxit < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 3663ab54825eSJed Brown snes->max_its = maxit; 3664ab54825eSJed Brown } 3665ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 3666e71169deSBarry Smith if (maxf < -1) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be -1 or nonnegative",maxf); 3667ab54825eSJed Brown snes->max_funcs = maxf; 3668ab54825eSJed Brown } 366988976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 36703a40ed3dSBarry Smith PetscFunctionReturn(0); 36719b94acceSBarry Smith } 36729b94acceSBarry Smith 3673e4d06f11SPatrick Farrell /*@ 3674e4d06f11SPatrick Farrell SNESSetDivergenceTolerance - Sets the divergence tolerance used for the SNES divergence test. 3675e4d06f11SPatrick Farrell 3676e4d06f11SPatrick Farrell Logically Collective on SNES 3677e4d06f11SPatrick Farrell 3678e4d06f11SPatrick Farrell Input Parameters: 3679e4d06f11SPatrick Farrell + snes - the SNES context 3680e4d06f11SPatrick Farrell - divtol - the divergence tolerance. Use -1 to deactivate the test. 3681e4d06f11SPatrick Farrell 3682e4d06f11SPatrick Farrell Options Database Keys: 3683a2b725a8SWilliam Gropp . -snes_divergence_tolerance <divtol> - Sets divtol 3684e4d06f11SPatrick Farrell 3685e4d06f11SPatrick Farrell Notes: 3686e4d06f11SPatrick Farrell The default divergence tolerance is 1e4. 3687e4d06f11SPatrick Farrell 3688e4d06f11SPatrick Farrell Level: intermediate 3689e4d06f11SPatrick Farrell 3690e4d06f11SPatrick Farrell .seealso: SNESSetTolerances(), SNESGetDivergenceTolerance 3691e4d06f11SPatrick Farrell @*/ 3692e4d06f11SPatrick Farrell PetscErrorCode SNESSetDivergenceTolerance(SNES snes,PetscReal divtol) 3693e4d06f11SPatrick Farrell { 3694e4d06f11SPatrick Farrell PetscFunctionBegin; 3695e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3696e4d06f11SPatrick Farrell PetscValidLogicalCollectiveReal(snes,divtol,2); 3697e4d06f11SPatrick Farrell 3698e4d06f11SPatrick Farrell if (divtol != PETSC_DEFAULT) { 3699e4d06f11SPatrick Farrell snes->divtol = divtol; 3700e4d06f11SPatrick Farrell } 3701e4d06f11SPatrick Farrell else { 3702e4d06f11SPatrick Farrell snes->divtol = 1.0e4; 3703e4d06f11SPatrick Farrell } 3704e4d06f11SPatrick Farrell PetscFunctionReturn(0); 3705e4d06f11SPatrick Farrell } 3706e4d06f11SPatrick Farrell 37079b94acceSBarry Smith /*@ 370833174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 370933174efeSLois Curfman McInnes 3710c7afd0dbSLois Curfman McInnes Not Collective 3711c7afd0dbSLois Curfman McInnes 371233174efeSLois Curfman McInnes Input Parameters: 3713c7afd0dbSLois Curfman McInnes + snes - the SNES context 371485385478SLisandro Dalcin . atol - absolute convergence tolerance 371533174efeSLois Curfman McInnes . rtol - relative convergence tolerance 371633174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 371733174efeSLois Curfman McInnes of the change in the solution between steps 371833174efeSLois Curfman McInnes . maxit - maximum number of iterations 3719c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 3720fee21e36SBarry Smith 372133174efeSLois Curfman McInnes Notes: 37220298fd71SBarry Smith The user can specify NULL for any parameter that is not needed. 372333174efeSLois Curfman McInnes 372436851e7fSLois Curfman McInnes Level: intermediate 372536851e7fSLois Curfman McInnes 372633174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 372733174efeSLois Curfman McInnes @*/ 37287087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 372933174efeSLois Curfman McInnes { 37303a40ed3dSBarry Smith PetscFunctionBegin; 37310700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 373285385478SLisandro Dalcin if (atol) *atol = snes->abstol; 373333174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 3734c60f73f4SPeter Brune if (stol) *stol = snes->stol; 373533174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 373633174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 37373a40ed3dSBarry Smith PetscFunctionReturn(0); 373833174efeSLois Curfman McInnes } 373933174efeSLois Curfman McInnes 3740e4d06f11SPatrick Farrell /*@ 3741e4d06f11SPatrick Farrell SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test. 3742e4d06f11SPatrick Farrell 3743e4d06f11SPatrick Farrell Not Collective 3744e4d06f11SPatrick Farrell 3745e4d06f11SPatrick Farrell Input Parameters: 3746e4d06f11SPatrick Farrell + snes - the SNES context 3747e4d06f11SPatrick Farrell - divtol - divergence tolerance 3748e4d06f11SPatrick Farrell 3749e4d06f11SPatrick Farrell Level: intermediate 3750e4d06f11SPatrick Farrell 3751e4d06f11SPatrick Farrell .seealso: SNESSetDivergenceTolerance() 3752e4d06f11SPatrick Farrell @*/ 3753e4d06f11SPatrick Farrell PetscErrorCode SNESGetDivergenceTolerance(SNES snes,PetscReal *divtol) 3754e4d06f11SPatrick Farrell { 3755e4d06f11SPatrick Farrell PetscFunctionBegin; 3756e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3757e4d06f11SPatrick Farrell if (divtol) *divtol = snes->divtol; 3758e4d06f11SPatrick Farrell PetscFunctionReturn(0); 3759e4d06f11SPatrick Farrell } 3760e4d06f11SPatrick Farrell 376133174efeSLois Curfman McInnes /*@ 37629b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 37639b94acceSBarry Smith 37643f9fe445SBarry Smith Logically Collective on SNES 3765fee21e36SBarry Smith 3766c7afd0dbSLois Curfman McInnes Input Parameters: 3767c7afd0dbSLois Curfman McInnes + snes - the SNES context 3768c7afd0dbSLois Curfman McInnes - tol - tolerance 3769c7afd0dbSLois Curfman McInnes 37709b94acceSBarry Smith Options Database Key: 3771c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 37729b94acceSBarry Smith 377336851e7fSLois Curfman McInnes Level: intermediate 377436851e7fSLois Curfman McInnes 37752492ecdbSBarry Smith .seealso: SNESSetTolerances() 37769b94acceSBarry Smith @*/ 37777087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 37789b94acceSBarry Smith { 37793a40ed3dSBarry Smith PetscFunctionBegin; 37800700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3781c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 37829b94acceSBarry Smith snes->deltatol = tol; 37833a40ed3dSBarry Smith PetscFunctionReturn(0); 37849b94acceSBarry Smith } 37859b94acceSBarry Smith 3786df9fa365SBarry Smith /* 3787df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 3788df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 3789df9fa365SBarry Smith macros instead of functions 3790df9fa365SBarry Smith */ 3791d96771aaSLisandro Dalcin PetscErrorCode SNESMonitorLGResidualNorm(SNES snes,PetscInt it,PetscReal norm,void *ctx) 3792ce1608b8SBarry Smith { 3793dfbe8321SBarry Smith PetscErrorCode ierr; 3794ce1608b8SBarry Smith 3795ce1608b8SBarry Smith PetscFunctionBegin; 37960700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3797d96771aaSLisandro Dalcin ierr = KSPMonitorLGResidualNorm((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 3798ce1608b8SBarry Smith PetscFunctionReturn(0); 3799ce1608b8SBarry Smith } 3800ce1608b8SBarry Smith 3801d96771aaSLisandro Dalcin PetscErrorCode SNESMonitorLGCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *lgctx) 3802df9fa365SBarry Smith { 3803dfbe8321SBarry Smith PetscErrorCode ierr; 3804df9fa365SBarry Smith 3805df9fa365SBarry Smith PetscFunctionBegin; 3806d96771aaSLisandro Dalcin ierr = KSPMonitorLGResidualNormCreate(comm,host,label,x,y,m,n,lgctx);CHKERRQ(ierr); 3807df9fa365SBarry Smith PetscFunctionReturn(0); 3808df9fa365SBarry Smith } 3809df9fa365SBarry Smith 38106ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 38116ba87a44SLisandro Dalcin 38127087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 3813b271bb04SBarry Smith { 3814b271bb04SBarry Smith PetscDrawLG lg; 3815b271bb04SBarry Smith PetscErrorCode ierr; 3816b271bb04SBarry Smith PetscReal x,y,per; 3817b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 3818b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 3819b271bb04SBarry Smith PetscDraw draw; 3820b271bb04SBarry Smith 3821459f5d12SBarry Smith PetscFunctionBegin; 38224d4332d5SBarry Smith PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,4); 3823b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 3824b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3825b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3826b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 3827b271bb04SBarry Smith x = (PetscReal)n; 382877b4d14cSPeter Brune if (rnorm > 0.0) y = PetscLog10Real(rnorm); 382994c9c6d3SKarl Rupp else y = -15.0; 3830b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 38316934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 3832b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 38336934998bSLisandro Dalcin ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3834b271bb04SBarry Smith } 3835b271bb04SBarry Smith 3836b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 3837b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3838b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3839b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 3840b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 3841b271bb04SBarry Smith x = (PetscReal)n; 3842b271bb04SBarry Smith y = 100.0*per; 3843b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 38446934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 3845b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 38466934998bSLisandro Dalcin ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3847b271bb04SBarry Smith } 3848b271bb04SBarry Smith 3849b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 3850b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3851b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3852b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 3853b271bb04SBarry Smith x = (PetscReal)n; 3854b271bb04SBarry Smith y = (prev - rnorm)/prev; 3855b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 38566934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 3857b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 38586934998bSLisandro Dalcin ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3859b271bb04SBarry Smith } 3860b271bb04SBarry Smith 3861b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 3862b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3863b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3864b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 3865b271bb04SBarry Smith x = (PetscReal)n; 3866b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 3867b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 3868b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3869b271bb04SBarry Smith } 38706934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 3871b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 38726934998bSLisandro Dalcin ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3873b271bb04SBarry Smith } 3874b271bb04SBarry Smith prev = rnorm; 3875b271bb04SBarry Smith PetscFunctionReturn(0); 3876b271bb04SBarry Smith } 3877b271bb04SBarry Smith 3878228d79bcSJed Brown /*@ 3879228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 3880228d79bcSJed Brown 3881228d79bcSJed Brown Collective on SNES 3882228d79bcSJed Brown 3883228d79bcSJed Brown Input Parameters: 3884228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 3885228d79bcSJed Brown . iter - iteration number 3886228d79bcSJed Brown - rnorm - relative norm of the residual 3887228d79bcSJed Brown 3888228d79bcSJed Brown Notes: 3889228d79bcSJed Brown This routine is called by the SNES implementations. 3890228d79bcSJed Brown It does not typically need to be called by the user. 3891228d79bcSJed Brown 3892228d79bcSJed Brown Level: developer 3893228d79bcSJed Brown 3894228d79bcSJed Brown .seealso: SNESMonitorSet() 3895228d79bcSJed Brown @*/ 38967a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 38977a03ce2fSLisandro Dalcin { 38987a03ce2fSLisandro Dalcin PetscErrorCode ierr; 38997a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 39007a03ce2fSLisandro Dalcin 39017a03ce2fSLisandro Dalcin PetscFunctionBegin; 39028860a134SJunchao Zhang ierr = VecLockReadPush(snes->vec_sol);CHKERRQ(ierr); 39037a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 39047a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 39057a03ce2fSLisandro Dalcin } 39068860a134SJunchao Zhang ierr = VecLockReadPop(snes->vec_sol);CHKERRQ(ierr); 39077a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 39087a03ce2fSLisandro Dalcin } 39097a03ce2fSLisandro Dalcin 39109b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 39119b94acceSBarry Smith 3912bf388a1fSBarry Smith /*MC 3913bf388a1fSBarry Smith SNESMonitorFunction - functional form passed to SNESMonitorSet() to monitor convergence of nonlinear solver 3914bf388a1fSBarry Smith 3915bf388a1fSBarry Smith Synopsis: 3916aaa7dc30SBarry Smith #include <petscsnes.h> 3917bf388a1fSBarry Smith $ PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx) 3918bf388a1fSBarry Smith 39191843f636SBarry Smith Collective on snes 39201843f636SBarry Smith 39211843f636SBarry Smith Input Parameters: 3922bf388a1fSBarry Smith + snes - the SNES context 3923bf388a1fSBarry Smith . its - iteration number 3924bf388a1fSBarry Smith . norm - 2-norm function value (may be estimated) 3925bf388a1fSBarry Smith - mctx - [optional] monitoring context 3926bf388a1fSBarry Smith 3927878cb397SSatish Balay Level: advanced 3928878cb397SSatish Balay 3929bf388a1fSBarry Smith .seealso: SNESMonitorSet(), SNESMonitorGet() 3930bf388a1fSBarry Smith M*/ 3931bf388a1fSBarry Smith 39329b94acceSBarry Smith /*@C 3933a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 39349b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 39359b94acceSBarry Smith progress. 39369b94acceSBarry Smith 39373f9fe445SBarry Smith Logically Collective on SNES 3938fee21e36SBarry Smith 3939c7afd0dbSLois Curfman McInnes Input Parameters: 3940c7afd0dbSLois Curfman McInnes + snes - the SNES context 39416e4dcb14SBarry Smith . f - the monitor function, see SNESMonitorFunction for the calling sequence 3942b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 39430298fd71SBarry Smith monitor routine (use NULL if no context is desired) 3944b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 39450298fd71SBarry Smith (may be NULL) 39469b94acceSBarry Smith 39479665c990SLois Curfman McInnes Options Database Keys: 3948a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 39494619e776SBarry Smith . -snes_monitor_lg_residualnorm - sets line graph monitor, 3950a6570f20SBarry Smith uses SNESMonitorLGCreate() 3951cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 3952c7afd0dbSLois Curfman McInnes been hardwired into a code by 3953a6570f20SBarry Smith calls to SNESMonitorSet(), but 3954c7afd0dbSLois Curfman McInnes does not cancel those set via 3955c7afd0dbSLois Curfman McInnes the options database. 39569665c990SLois Curfman McInnes 3957639f9d9dSBarry Smith Notes: 39586bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 3959a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 39606bc08f3fSLois Curfman McInnes order in which they were set. 3961639f9d9dSBarry Smith 396295452b02SPatrick Sanan Fortran Notes: 396395452b02SPatrick Sanan Only a single monitor function can be set for each SNES object 3964025f1a04SBarry Smith 396536851e7fSLois Curfman McInnes Level: intermediate 396636851e7fSLois Curfman McInnes 3967bf388a1fSBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel(), SNESMonitorFunction 39689b94acceSBarry Smith @*/ 39696e4dcb14SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*f)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 39709b94acceSBarry Smith { 3971b90d0a6eSBarry Smith PetscInt i; 3972649052a6SBarry Smith PetscErrorCode ierr; 397378064530SBarry Smith PetscBool identical; 3974b90d0a6eSBarry Smith 39753a40ed3dSBarry Smith PetscFunctionBegin; 39760700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3977b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 397878064530SBarry Smith ierr = PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))snes->monitor[i],snes->monitorcontext[i],snes->monitordestroy[i],&identical);CHKERRQ(ierr); 397978064530SBarry Smith if (identical) PetscFunctionReturn(0); 3980649052a6SBarry Smith } 398178064530SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 39826e4dcb14SBarry Smith snes->monitor[snes->numbermonitors] = f; 3983b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 3984639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 39853a40ed3dSBarry Smith PetscFunctionReturn(0); 39869b94acceSBarry Smith } 39879b94acceSBarry Smith 3988a278d85bSSatish Balay /*@ 3989a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 39905cd90555SBarry Smith 39913f9fe445SBarry Smith Logically Collective on SNES 3992c7afd0dbSLois Curfman McInnes 39935cd90555SBarry Smith Input Parameters: 39945cd90555SBarry Smith . snes - the SNES context 39955cd90555SBarry Smith 39961a480d89SAdministrator Options Database Key: 3997a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 3998a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 3999c7afd0dbSLois Curfman McInnes set via the options database 40005cd90555SBarry Smith 40015cd90555SBarry Smith Notes: 40025cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 40035cd90555SBarry Smith 400436851e7fSLois Curfman McInnes Level: intermediate 400536851e7fSLois Curfman McInnes 4006a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 40075cd90555SBarry Smith @*/ 40087087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 40095cd90555SBarry Smith { 4010d952e501SBarry Smith PetscErrorCode ierr; 4011d952e501SBarry Smith PetscInt i; 4012d952e501SBarry Smith 40135cd90555SBarry Smith PetscFunctionBegin; 40140700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4015d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 4016d952e501SBarry Smith if (snes->monitordestroy[i]) { 40173c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 4018d952e501SBarry Smith } 4019d952e501SBarry Smith } 40205cd90555SBarry Smith snes->numbermonitors = 0; 40215cd90555SBarry Smith PetscFunctionReturn(0); 40225cd90555SBarry Smith } 40235cd90555SBarry Smith 4024bf388a1fSBarry Smith /*MC 4025bf388a1fSBarry Smith SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver 4026bf388a1fSBarry Smith 4027bf388a1fSBarry Smith Synopsis: 4028aaa7dc30SBarry Smith #include <petscsnes.h> 4029bf388a1fSBarry Smith $ PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 4030bf388a1fSBarry Smith 40311843f636SBarry Smith Collective on snes 40321843f636SBarry Smith 40331843f636SBarry Smith Input Parameters: 4034bf388a1fSBarry Smith + snes - the SNES context 4035bf388a1fSBarry Smith . it - current iteration (0 is the first and is before any Newton step) 4036bf388a1fSBarry Smith . xnorm - 2-norm of current iterate 4037bf388a1fSBarry Smith . gnorm - 2-norm of current step 40381843f636SBarry Smith . f - 2-norm of function 40391843f636SBarry Smith - cctx - [optional] convergence context 40401843f636SBarry Smith 40411843f636SBarry Smith Output Parameter: 40421843f636SBarry Smith . reason - reason for convergence/divergence, only needs to be set when convergence or divergence is detected 4043bf388a1fSBarry Smith 4044878cb397SSatish Balay Level: intermediate 4045bf388a1fSBarry Smith 4046bf388a1fSBarry Smith .seealso: SNESSetConvergenceTest(), SNESGetConvergenceTest() 4047bf388a1fSBarry Smith M*/ 4048bf388a1fSBarry Smith 40499b94acceSBarry Smith /*@C 40509b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 40519b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 40529b94acceSBarry Smith 40533f9fe445SBarry Smith Logically Collective on SNES 4054fee21e36SBarry Smith 4055c7afd0dbSLois Curfman McInnes Input Parameters: 4056c7afd0dbSLois Curfman McInnes + snes - the SNES context 4057bf388a1fSBarry Smith . SNESConvergenceTestFunction - routine to test for convergence 40580298fd71SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be NULL) 4059cf90aa19SBarry Smith - destroy - [optional] destructor for the context (may be NULL; PETSC_NULL_FUNCTION in Fortran) 40609b94acceSBarry Smith 406136851e7fSLois Curfman McInnes Level: advanced 406236851e7fSLois Curfman McInnes 4063e2a6519dSDmitry Karpeev .seealso: SNESConvergedDefault(), SNESConvergedSkip(), SNESConvergenceTestFunction 40649b94acceSBarry Smith @*/ 4065bf388a1fSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 40669b94acceSBarry Smith { 40677f7931b9SBarry Smith PetscErrorCode ierr; 40687f7931b9SBarry Smith 40693a40ed3dSBarry Smith PetscFunctionBegin; 40700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4071e2a6519dSDmitry Karpeev if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip; 40727f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 40737f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 40747f7931b9SBarry Smith } 4075bf388a1fSBarry Smith snes->ops->converged = SNESConvergenceTestFunction; 40767f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 407785385478SLisandro Dalcin snes->cnvP = cctx; 40783a40ed3dSBarry Smith PetscFunctionReturn(0); 40799b94acceSBarry Smith } 40809b94acceSBarry Smith 408152baeb72SSatish Balay /*@ 4082184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 4083184914b5SBarry Smith 4084184914b5SBarry Smith Not Collective 4085184914b5SBarry Smith 4086184914b5SBarry Smith Input Parameter: 4087184914b5SBarry Smith . snes - the SNES context 4088184914b5SBarry Smith 4089184914b5SBarry Smith Output Parameter: 40904d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 4091184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 4092184914b5SBarry Smith 40936a4d7782SBarry Smith Options Database: 40946a4d7782SBarry Smith . -snes_converged_reason - prints the reason to standard out 40956a4d7782SBarry Smith 4096184914b5SBarry Smith Level: intermediate 4097184914b5SBarry Smith 409895452b02SPatrick Sanan Notes: 409995452b02SPatrick Sanan Should only be called after the call the SNESSolve() is complete, if it is called earlier it returns the value SNES__CONVERGED_ITERATING. 4100184914b5SBarry Smith 410133866048SMatthew G. Knepley .seealso: SNESSetConvergenceTest(), SNESSetConvergedReason(), SNESConvergedReason 4102184914b5SBarry Smith @*/ 41037087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 4104184914b5SBarry Smith { 4105184914b5SBarry Smith PetscFunctionBegin; 41060700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 41074482741eSBarry Smith PetscValidPointer(reason,2); 4108184914b5SBarry Smith *reason = snes->reason; 4109184914b5SBarry Smith PetscFunctionReturn(0); 4110184914b5SBarry Smith } 4111184914b5SBarry Smith 411233866048SMatthew G. Knepley /*@ 411333866048SMatthew G. Knepley SNESSetConvergedReason - Sets the reason the SNES iteration was stopped. 411433866048SMatthew G. Knepley 411533866048SMatthew G. Knepley Not Collective 411633866048SMatthew G. Knepley 411733866048SMatthew G. Knepley Input Parameters: 411833866048SMatthew G. Knepley + snes - the SNES context 411933866048SMatthew G. Knepley - reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 412033866048SMatthew G. Knepley manual pages for the individual convergence tests for complete lists 412133866048SMatthew G. Knepley 412233866048SMatthew G. Knepley Level: intermediate 412333866048SMatthew G. Knepley 412433866048SMatthew G. Knepley .seealso: SNESGetConvergedReason(), SNESSetConvergenceTest(), SNESConvergedReason 412533866048SMatthew G. Knepley @*/ 412633866048SMatthew G. Knepley PetscErrorCode SNESSetConvergedReason(SNES snes,SNESConvergedReason reason) 412733866048SMatthew G. Knepley { 412833866048SMatthew G. Knepley PetscFunctionBegin; 412933866048SMatthew G. Knepley PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 413033866048SMatthew G. Knepley snes->reason = reason; 413133866048SMatthew G. Knepley PetscFunctionReturn(0); 413233866048SMatthew G. Knepley } 413333866048SMatthew G. Knepley 4134c9005455SLois Curfman McInnes /*@ 4135c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 4136c9005455SLois Curfman McInnes 41373f9fe445SBarry Smith Logically Collective on SNES 4138fee21e36SBarry Smith 4139c7afd0dbSLois Curfman McInnes Input Parameters: 4140c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 41418c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 4142cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 4143758f92a0SBarry Smith . na - size of a and its 414464731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 4145758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 4146c7afd0dbSLois Curfman McInnes 4147308dcc3eSBarry Smith Notes: 41480298fd71SBarry Smith If 'a' and 'its' are NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 4149308dcc3eSBarry Smith default array of length 10000 is allocated. 4150308dcc3eSBarry Smith 4151c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 4152c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 4153c9005455SLois Curfman McInnes during the section of code that is being timed. 4154c9005455SLois Curfman McInnes 415536851e7fSLois Curfman McInnes Level: intermediate 415636851e7fSLois Curfman McInnes 415708405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 4158758f92a0SBarry Smith 4159c9005455SLois Curfman McInnes @*/ 41607087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 4161c9005455SLois Curfman McInnes { 4162308dcc3eSBarry Smith PetscErrorCode ierr; 4163308dcc3eSBarry Smith 41643a40ed3dSBarry Smith PetscFunctionBegin; 41650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 41667a1ec6d4SBarry Smith if (a) PetscValidScalarPointer(a,2); 4167a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 41687a1ec6d4SBarry Smith if (!a) { 4169308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 4170071fcb05SBarry Smith ierr = PetscCalloc2(na,&a,na,&its);CHKERRQ(ierr); 4171071fcb05SBarry Smith snes->conv_hist_alloc = PETSC_TRUE; 4172308dcc3eSBarry Smith } 4173c9005455SLois Curfman McInnes snes->conv_hist = a; 4174758f92a0SBarry Smith snes->conv_hist_its = its; 4175758f92a0SBarry Smith snes->conv_hist_max = na; 4176a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 4177758f92a0SBarry Smith snes->conv_hist_reset = reset; 4178758f92a0SBarry Smith PetscFunctionReturn(0); 4179758f92a0SBarry Smith } 4180758f92a0SBarry Smith 4181308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4182c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 4183c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 418499e0435eSBarry Smith 41858cc058d9SJed Brown PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 4186308dcc3eSBarry Smith { 4187308dcc3eSBarry Smith mxArray *mat; 4188308dcc3eSBarry Smith PetscInt i; 4189308dcc3eSBarry Smith PetscReal *ar; 4190308dcc3eSBarry Smith 4191308dcc3eSBarry Smith PetscFunctionBegin; 4192308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 4193308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 4194f5af7f23SKarl Rupp for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i]; 4195308dcc3eSBarry Smith PetscFunctionReturn(mat); 4196308dcc3eSBarry Smith } 4197308dcc3eSBarry Smith #endif 4198308dcc3eSBarry Smith 41990c4c9dddSBarry Smith /*@C 4200758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 4201758f92a0SBarry Smith 42023f9fe445SBarry Smith Not Collective 4203758f92a0SBarry Smith 4204758f92a0SBarry Smith Input Parameter: 4205758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 4206758f92a0SBarry Smith 4207758f92a0SBarry Smith Output Parameters: 4208a2b725a8SWilliam Gropp + a - array to hold history 4209758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 4210758f92a0SBarry Smith negative if not converged) for each solve. 4211758f92a0SBarry Smith - na - size of a and its 4212758f92a0SBarry Smith 4213758f92a0SBarry Smith Notes: 4214758f92a0SBarry Smith The calling sequence for this routine in Fortran is 4215758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 4216758f92a0SBarry Smith 4217758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 4218758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 4219758f92a0SBarry Smith during the section of code that is being timed. 4220758f92a0SBarry Smith 4221758f92a0SBarry Smith Level: intermediate 4222758f92a0SBarry Smith 42235ea7661aSPierre Jolivet .seealso: SNESSetConvergenceHistory() 4224758f92a0SBarry Smith 4225758f92a0SBarry Smith @*/ 42267087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 4227758f92a0SBarry Smith { 4228758f92a0SBarry Smith PetscFunctionBegin; 42290700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4230758f92a0SBarry Smith if (a) *a = snes->conv_hist; 4231758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 4232758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 42333a40ed3dSBarry Smith PetscFunctionReturn(0); 4234c9005455SLois Curfman McInnes } 4235c9005455SLois Curfman McInnes 4236ac226902SBarry Smith /*@C 423776b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 4238eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 42397e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 424076b2cf59SMatthew Knepley 42413f9fe445SBarry Smith Logically Collective on SNES 424276b2cf59SMatthew Knepley 424376b2cf59SMatthew Knepley Input Parameters: 4244a2b725a8SWilliam Gropp + snes - The nonlinear solver context 4245a2b725a8SWilliam Gropp - func - The function 424676b2cf59SMatthew Knepley 424776b2cf59SMatthew Knepley Calling sequence of func: 4248a2b725a8SWilliam Gropp $ func (SNES snes, PetscInt step); 424976b2cf59SMatthew Knepley 425076b2cf59SMatthew Knepley . step - The current step of the iteration 425176b2cf59SMatthew Knepley 4252fe97e370SBarry Smith Level: advanced 4253fe97e370SBarry Smith 4254fe97e370SBarry 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() 4255fe97e370SBarry Smith This is not used by most users. 425676b2cf59SMatthew Knepley 42578d359177SBarry Smith .seealso SNESSetJacobian(), SNESSolve() 425876b2cf59SMatthew Knepley @*/ 42597087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 426076b2cf59SMatthew Knepley { 426176b2cf59SMatthew Knepley PetscFunctionBegin; 42620700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 4263e7788613SBarry Smith snes->ops->update = func; 426476b2cf59SMatthew Knepley PetscFunctionReturn(0); 426576b2cf59SMatthew Knepley } 426676b2cf59SMatthew Knepley 42679b94acceSBarry Smith /* 42689b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 42699b94acceSBarry Smith positive parameter delta. 42709b94acceSBarry Smith 42719b94acceSBarry Smith Input Parameters: 4272c7afd0dbSLois Curfman McInnes + snes - the SNES context 42739b94acceSBarry Smith . y - approximate solution of linear system 42749b94acceSBarry Smith . fnorm - 2-norm of current function 4275c7afd0dbSLois Curfman McInnes - delta - trust region size 42769b94acceSBarry Smith 42779b94acceSBarry Smith Output Parameters: 4278c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 42799b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 42809b94acceSBarry Smith region, and exceeds zero otherwise. 4281c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 42829b94acceSBarry Smith 42839b94acceSBarry Smith Note: 428404d7464bSBarry Smith For non-trust region methods such as SNESNEWTONLS, the parameter delta 42859b94acceSBarry Smith is set to be the maximum allowable step size. 42869b94acceSBarry Smith 42879b94acceSBarry Smith */ 4288dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 42899b94acceSBarry Smith { 4290064f8208SBarry Smith PetscReal nrm; 4291ea709b57SSatish Balay PetscScalar cnorm; 4292dfbe8321SBarry Smith PetscErrorCode ierr; 42933a40ed3dSBarry Smith 42943a40ed3dSBarry Smith PetscFunctionBegin; 42950700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 42960700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 4297c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 4298184914b5SBarry Smith 4299064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 4300064f8208SBarry Smith if (nrm > *delta) { 4301064f8208SBarry Smith nrm = *delta/nrm; 4302064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 4303064f8208SBarry Smith cnorm = nrm; 43042dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 43059b94acceSBarry Smith *ynorm = *delta; 43069b94acceSBarry Smith } else { 43079b94acceSBarry Smith *gpnorm = 0.0; 4308064f8208SBarry Smith *ynorm = nrm; 43099b94acceSBarry Smith } 43103a40ed3dSBarry Smith PetscFunctionReturn(0); 43119b94acceSBarry Smith } 43129b94acceSBarry Smith 431391f3e32bSBarry Smith /*@C 431419a666eeSBarry Smith SNESConvergedReasonView - Displays the reason a SNES solve converged or diverged to a viewer 43152a359c20SBarry Smith 43162a359c20SBarry Smith Collective on SNES 43172a359c20SBarry Smith 43182a359c20SBarry Smith Parameter: 43192a359c20SBarry Smith + snes - iterative context obtained from SNESCreate() 43202a359c20SBarry Smith - viewer - the viewer to display the reason 43212a359c20SBarry Smith 43222a359c20SBarry Smith 43232a359c20SBarry Smith Options Database Keys: 4324ee300463SSatish Balay + -snes_converged_reason - print reason for converged or diverged, also prints number of iterations 4325ee300463SSatish Balay - -snes_converged_reason ::failed - only print reason and number of iterations when diverged 4326eafd5ff0SAlex Lindsay 432719a666eeSBarry Smith Notes: 432819a666eeSBarry Smith To change the format of the output call PetscViewerPushFormat(viewer,format) before this call. Use PETSC_VIEWER_DEFAULT for the default, 432919a666eeSBarry Smith use PETSC_VIEWER_FAILED to only display a reason if it fails. 43302a359c20SBarry Smith 43312a359c20SBarry Smith Level: beginner 43322a359c20SBarry Smith 433319a666eeSBarry Smith .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault(), SNESGetConvergedReason(), SNESConvergedReasonViewFromOptions(), 433419a666eeSBarry Smith PetscViewerPushFormat(), PetscViewerPopFormat() 43352a359c20SBarry Smith 43362a359c20SBarry Smith @*/ 433719a666eeSBarry Smith PetscErrorCode SNESConvergedReasonView(SNES snes,PetscViewer viewer) 43382a359c20SBarry Smith { 433975cca76cSMatthew G. Knepley PetscViewerFormat format; 43402a359c20SBarry Smith PetscBool isAscii; 434175cca76cSMatthew G. Knepley PetscErrorCode ierr; 43422a359c20SBarry Smith 43432a359c20SBarry Smith PetscFunctionBegin; 434419a666eeSBarry Smith if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 43452a359c20SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);CHKERRQ(ierr); 43462a359c20SBarry Smith if (isAscii) { 434775cca76cSMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 43482a359c20SBarry Smith ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 434975cca76cSMatthew G. Knepley if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 435075cca76cSMatthew G. Knepley DM dm; 435175cca76cSMatthew G. Knepley Vec u; 435275cca76cSMatthew G. Knepley PetscDS prob; 435375cca76cSMatthew G. Knepley PetscInt Nf, f; 435495cbbfd3SMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 435595cbbfd3SMatthew G. Knepley void **exactCtx; 435675cca76cSMatthew G. Knepley PetscReal error; 435775cca76cSMatthew G. Knepley 435875cca76cSMatthew G. Knepley ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 435975cca76cSMatthew G. Knepley ierr = SNESGetSolution(snes, &u);CHKERRQ(ierr); 436075cca76cSMatthew G. Knepley ierr = DMGetDS(dm, &prob);CHKERRQ(ierr); 436175cca76cSMatthew G. Knepley ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 436295cbbfd3SMatthew G. Knepley ierr = PetscMalloc2(Nf, &exactSol, Nf, &exactCtx);CHKERRQ(ierr); 436395cbbfd3SMatthew G. Knepley for (f = 0; f < Nf; ++f) {ierr = PetscDSGetExactSolution(prob, f, &exactSol[f], &exactCtx[f]);CHKERRQ(ierr);} 436495cbbfd3SMatthew G. Knepley ierr = DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error);CHKERRQ(ierr); 436595cbbfd3SMatthew G. Knepley ierr = PetscFree2(exactSol, exactCtx);CHKERRQ(ierr); 436675cca76cSMatthew G. Knepley if (error < 1.0e-11) {ierr = PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n");CHKERRQ(ierr);} 436775cca76cSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", error);CHKERRQ(ierr);} 436875cca76cSMatthew G. Knepley } 4369eafd5ff0SAlex Lindsay if (snes->reason > 0 && format != PETSC_VIEWER_FAILED) { 43702a359c20SBarry Smith if (((PetscObject) snes)->prefix) { 43712a359c20SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve converged due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 43722a359c20SBarry Smith } else { 43732a359c20SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 43742a359c20SBarry Smith } 4375eafd5ff0SAlex Lindsay } else if (snes->reason <= 0) { 43762a359c20SBarry Smith if (((PetscObject) snes)->prefix) { 43772a359c20SBarry 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); 43782a359c20SBarry Smith } else { 43792a359c20SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 43802a359c20SBarry Smith } 43812a359c20SBarry Smith } 43822a359c20SBarry Smith ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 43832a359c20SBarry Smith } 43842a359c20SBarry Smith PetscFunctionReturn(0); 43852a359c20SBarry Smith } 43862a359c20SBarry Smith 438791f3e32bSBarry Smith /*@ 438819a666eeSBarry Smith SNESConvergedReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed. 43892a359c20SBarry Smith 43902a359c20SBarry Smith Collective on SNES 43912a359c20SBarry Smith 43922a359c20SBarry Smith Input Parameters: 43932a359c20SBarry Smith . snes - the SNES object 43942a359c20SBarry Smith 43952a359c20SBarry Smith Level: intermediate 43962a359c20SBarry Smith 439719a666eeSBarry Smith .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault(), SNESGetConvergedReason(), SNESConvergedReasonView() 439819a666eeSBarry Smith 43992a359c20SBarry Smith @*/ 440019a666eeSBarry Smith PetscErrorCode SNESConvergedReasonViewFromOptions(SNES snes) 44012a359c20SBarry Smith { 44022a359c20SBarry Smith PetscErrorCode ierr; 44032a359c20SBarry Smith PetscViewer viewer; 44042a359c20SBarry Smith PetscBool flg; 44052a359c20SBarry Smith static PetscBool incall = PETSC_FALSE; 44062a359c20SBarry Smith PetscViewerFormat format; 44072a359c20SBarry Smith 44082a359c20SBarry Smith PetscFunctionBegin; 44092a359c20SBarry Smith if (incall) PetscFunctionReturn(0); 44102a359c20SBarry Smith incall = PETSC_TRUE; 441116413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_converged_reason",&viewer,&format,&flg);CHKERRQ(ierr); 44122a359c20SBarry Smith if (flg) { 44132a359c20SBarry Smith ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 441419a666eeSBarry Smith ierr = SNESConvergedReasonView(snes,viewer);CHKERRQ(ierr); 44152a359c20SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 44162a359c20SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 44172a359c20SBarry Smith } 44182a359c20SBarry Smith incall = PETSC_FALSE; 44192a359c20SBarry Smith PetscFunctionReturn(0); 44202a359c20SBarry Smith } 44212a359c20SBarry Smith 4422487a658cSBarry Smith /*@ 4423f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 4424f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 44259b94acceSBarry Smith 4426c7afd0dbSLois Curfman McInnes Collective on SNES 4427c7afd0dbSLois Curfman McInnes 4428b2002411SLois Curfman McInnes Input Parameters: 4429c7afd0dbSLois Curfman McInnes + snes - the SNES context 44300298fd71SBarry Smith . b - the constant part of the equation F(x) = b, or NULL to use zero. 443185385478SLisandro Dalcin - x - the solution vector. 44329b94acceSBarry Smith 4433b2002411SLois Curfman McInnes Notes: 44348ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 44358ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 44368ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 44378ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 44388ddd3da0SLois Curfman McInnes 443936851e7fSLois Curfman McInnes Level: beginner 444036851e7fSLois Curfman McInnes 4441c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 44429b94acceSBarry Smith @*/ 44437087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 44449b94acceSBarry Smith { 4445dfbe8321SBarry Smith PetscErrorCode ierr; 4446ace3abfcSBarry Smith PetscBool flg; 4447efd51863SBarry Smith PetscInt grid; 44480298fd71SBarry Smith Vec xcreated = NULL; 4449caa4e7f2SJed Brown DM dm; 4450052efed2SBarry Smith 44513a40ed3dSBarry Smith PetscFunctionBegin; 44520700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4453a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 4454a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 44550700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 445685385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 445785385478SLisandro Dalcin 445834b4d3a8SMatthew G. Knepley /* High level operations using the nonlinear solver */ 445906fc46c8SMatthew G. Knepley { 446006fc46c8SMatthew G. Knepley PetscViewer viewer; 446106fc46c8SMatthew G. Knepley PetscViewerFormat format; 44627c88af5aSMatthew G. Knepley PetscInt num; 446306fc46c8SMatthew G. Knepley PetscBool flg; 446406fc46c8SMatthew G. Knepley static PetscBool incall = PETSC_FALSE; 446506fc46c8SMatthew G. Knepley 446606fc46c8SMatthew G. Knepley if (!incall) { 446734b4d3a8SMatthew G. Knepley /* Estimate the convergence rate of the discretization */ 446816413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) snes),((PetscObject)snes)->options, ((PetscObject) snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg);CHKERRQ(ierr); 446906fc46c8SMatthew G. Knepley if (flg) { 447006fc46c8SMatthew G. Knepley PetscConvEst conv; 447146079b62SMatthew G. Knepley DM dm; 447246079b62SMatthew G. Knepley PetscReal *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */ 447346079b62SMatthew G. Knepley PetscInt Nf; 447406fc46c8SMatthew G. Knepley 447506fc46c8SMatthew G. Knepley incall = PETSC_TRUE; 447646079b62SMatthew G. Knepley ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 447746079b62SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 4478ca5a3622SMatthew G. Knepley ierr = PetscCalloc1(Nf, &alpha);CHKERRQ(ierr); 447906fc46c8SMatthew G. Knepley ierr = PetscConvEstCreate(PetscObjectComm((PetscObject) snes), &conv);CHKERRQ(ierr); 4480900f6b5bSMatthew G. Knepley ierr = PetscConvEstSetSolver(conv, (PetscObject) snes);CHKERRQ(ierr); 448106fc46c8SMatthew G. Knepley ierr = PetscConvEstSetFromOptions(conv);CHKERRQ(ierr); 44820955ed61SMatthew G. Knepley ierr = PetscConvEstSetUp(conv);CHKERRQ(ierr); 448346079b62SMatthew G. Knepley ierr = PetscConvEstGetConvRate(conv, alpha);CHKERRQ(ierr); 448406fc46c8SMatthew G. Knepley ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr); 448506fc46c8SMatthew G. Knepley ierr = PetscConvEstRateView(conv, alpha, viewer);CHKERRQ(ierr); 448606fc46c8SMatthew G. Knepley ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 448706fc46c8SMatthew G. Knepley ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 448806fc46c8SMatthew G. Knepley ierr = PetscConvEstDestroy(&conv);CHKERRQ(ierr); 448946079b62SMatthew G. Knepley ierr = PetscFree(alpha);CHKERRQ(ierr); 449006fc46c8SMatthew G. Knepley incall = PETSC_FALSE; 449106fc46c8SMatthew G. Knepley } 449234b4d3a8SMatthew G. Knepley /* Adaptively refine the initial grid */ 4493b2588ea6SMatthew G. Knepley num = 1; 4494b2588ea6SMatthew G. Knepley ierr = PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_initial", &num, &flg);CHKERRQ(ierr); 449534b4d3a8SMatthew G. Knepley if (flg) { 449634b4d3a8SMatthew G. Knepley DMAdaptor adaptor; 449734b4d3a8SMatthew G. Knepley 449834b4d3a8SMatthew G. Knepley incall = PETSC_TRUE; 4499ea13f565SStefano Zampini ierr = DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor);CHKERRQ(ierr); 450034b4d3a8SMatthew G. Knepley ierr = DMAdaptorSetSolver(adaptor, snes);CHKERRQ(ierr); 4501b2588ea6SMatthew G. Knepley ierr = DMAdaptorSetSequenceLength(adaptor, num);CHKERRQ(ierr); 450234b4d3a8SMatthew G. Knepley ierr = DMAdaptorSetFromOptions(adaptor);CHKERRQ(ierr); 450334b4d3a8SMatthew G. Knepley ierr = DMAdaptorSetUp(adaptor);CHKERRQ(ierr); 450434b4d3a8SMatthew G. Knepley ierr = DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x);CHKERRQ(ierr); 450534b4d3a8SMatthew G. Knepley ierr = DMAdaptorDestroy(&adaptor);CHKERRQ(ierr); 450634b4d3a8SMatthew G. Knepley incall = PETSC_FALSE; 450734b4d3a8SMatthew G. Knepley } 45087c88af5aSMatthew G. Knepley /* Use grid sequencing to adapt */ 45097c88af5aSMatthew G. Knepley num = 0; 45107c88af5aSMatthew G. Knepley ierr = PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_sequence", &num, NULL);CHKERRQ(ierr); 45117c88af5aSMatthew G. Knepley if (num) { 45127c88af5aSMatthew G. Knepley DMAdaptor adaptor; 45137c88af5aSMatthew G. Knepley 45147c88af5aSMatthew G. Knepley incall = PETSC_TRUE; 4515ea13f565SStefano Zampini ierr = DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor);CHKERRQ(ierr); 45167c88af5aSMatthew G. Knepley ierr = DMAdaptorSetSolver(adaptor, snes);CHKERRQ(ierr); 45177c88af5aSMatthew G. Knepley ierr = DMAdaptorSetSequenceLength(adaptor, num);CHKERRQ(ierr); 45187c88af5aSMatthew G. Knepley ierr = DMAdaptorSetFromOptions(adaptor);CHKERRQ(ierr); 45197c88af5aSMatthew G. Knepley ierr = DMAdaptorSetUp(adaptor);CHKERRQ(ierr); 45207c88af5aSMatthew G. Knepley ierr = DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x);CHKERRQ(ierr); 45217c88af5aSMatthew G. Knepley ierr = DMAdaptorDestroy(&adaptor);CHKERRQ(ierr); 45227c88af5aSMatthew G. Knepley incall = PETSC_FALSE; 45237c88af5aSMatthew G. Knepley } 452406fc46c8SMatthew G. Knepley } 452506fc46c8SMatthew G. Knepley } 4526caa4e7f2SJed Brown if (!x) { 4527caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4528caa4e7f2SJed Brown ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 4529a69afd8bSBarry Smith x = xcreated; 4530a69afd8bSBarry Smith } 4531ce1779c8SBarry Smith ierr = SNESViewFromOptions(snes,NULL,"-snes_view_pre");CHKERRQ(ierr); 4532f05ece33SBarry Smith 4533ce94432eSBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);} 4534efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 4535efd51863SBarry Smith 453685385478SLisandro Dalcin /* set solution vector */ 4537efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 45386bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 453985385478SLisandro Dalcin snes->vec_sol = x; 4540caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4541caa4e7f2SJed Brown 4542caa4e7f2SJed Brown /* set affine vector if provided */ 454385385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 45446bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 454585385478SLisandro Dalcin snes->vec_rhs = b; 454685385478SLisandro Dalcin 4547bfdd6862SPatrick 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"); 4548154060b5SMatthew G. Knepley if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 4549154060b5SMatthew 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"); 4550154060b5SMatthew G. Knepley if (!snes->vec_sol_update /* && snes->vec_sol */) { 4551154060b5SMatthew G. Knepley ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 4552154060b5SMatthew G. Knepley ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update);CHKERRQ(ierr); 4553154060b5SMatthew G. Knepley } 4554154060b5SMatthew G. Knepley ierr = DMShellSetGlobalVector(dm,snes->vec_sol);CHKERRQ(ierr); 455570e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 45563f149594SLisandro Dalcin 45577eee914bSBarry Smith if (!grid) { 45587eee914bSBarry Smith if (snes->ops->computeinitialguess) { 4559d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 4560d25893d9SBarry Smith } 4561dd568438SSatish Balay } 4562d25893d9SBarry Smith 4563abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 4564971e163fSPeter Brune if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;} 4565d5e45103SBarry Smith 45663f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 45674936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 456885385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 456917186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 4570422a814eSBarry Smith snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */ 45713f149594SLisandro Dalcin 457237ec4e1aSPeter Brune if (snes->lagjac_persist) snes->jac_iter += snes->iter; 457337ec4e1aSPeter Brune if (snes->lagpre_persist) snes->pre_iter += snes->iter; 457437ec4e1aSPeter Brune 457516413a6aSBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_test_local_min",NULL,NULL,&flg);CHKERRQ(ierr); 4576da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 457719a666eeSBarry Smith ierr = SNESConvergedReasonViewFromOptions(snes);CHKERRQ(ierr); 45785968eb51SBarry Smith 4579ce94432eSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 45809c8e83a9SBarry Smith if (snes->reason < 0) break; 4581efd51863SBarry Smith if (grid < snes->gridsequence) { 4582efd51863SBarry Smith DM fine; 4583efd51863SBarry Smith Vec xnew; 4584efd51863SBarry Smith Mat interp; 4585efd51863SBarry Smith 4586ce94432eSBarry Smith ierr = DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine);CHKERRQ(ierr); 4587ce94432eSBarry Smith if (!fine) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 45880298fd71SBarry Smith ierr = DMCreateInterpolation(snes->dm,fine,&interp,NULL);CHKERRQ(ierr); 4589efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 4590efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 4591c833c3b5SJed Brown ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr); 4592efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 4593efd51863SBarry Smith x = xnew; 4594efd51863SBarry Smith 4595efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 4596efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 4597352f405dSMatthew G. Knepley ierr = SNESResetFromOptions(snes);CHKERRQ(ierr); 4598efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 4599ce94432eSBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr); 4600efd51863SBarry Smith } 4601efd51863SBarry Smith } 4602ce1779c8SBarry Smith ierr = SNESViewFromOptions(snes,NULL,"-snes_view");CHKERRQ(ierr); 4603685405a1SBarry Smith ierr = VecViewFromOptions(snes->vec_sol,(PetscObject)snes,"-snes_view_solution");CHKERRQ(ierr); 4604c0f0dcc3SMatthew G. Knepley ierr = DMMonitor(snes->dm);CHKERRQ(ierr); 46053f7e2da0SPeter Brune 4606a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 4607e04113cfSBarry Smith ierr = PetscObjectSAWsBlock((PetscObject)snes);CHKERRQ(ierr); 46083a40ed3dSBarry Smith PetscFunctionReturn(0); 46099b94acceSBarry Smith } 46109b94acceSBarry Smith 46119b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 46129b94acceSBarry Smith 461382bf6240SBarry Smith /*@C 46144b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 46159b94acceSBarry Smith 4616fee21e36SBarry Smith Collective on SNES 4617fee21e36SBarry Smith 4618c7afd0dbSLois Curfman McInnes Input Parameters: 4619c7afd0dbSLois Curfman McInnes + snes - the SNES context 4620454a90a3SBarry Smith - type - a known method 4621c7afd0dbSLois Curfman McInnes 4622c7afd0dbSLois Curfman McInnes Options Database Key: 4623454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 462404d7464bSBarry Smith of available methods (for instance, newtonls or newtontr) 4625ae12b187SLois Curfman McInnes 46269b94acceSBarry Smith Notes: 4627e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 462804d7464bSBarry Smith + SNESNEWTONLS - Newton's method with line search 4629c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 4630a2b725a8SWilliam Gropp - SNESNEWTONTR - Newton's method with trust region 4631c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 46329b94acceSBarry Smith 4633ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 4634ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 4635ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 4636ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 4637ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 4638ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 4639ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 4640ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 4641ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 4642b0a32e0cSBarry Smith appropriate method. 464336851e7fSLois Curfman McInnes 464495452b02SPatrick Sanan Developer Notes: 464595452b02SPatrick Sanan SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates 46468f6c3df8SBarry Smith the constructor in that list and calls it to create the spexific object. 46478f6c3df8SBarry Smith 464836851e7fSLois Curfman McInnes Level: intermediate 4649a703fe33SLois Curfman McInnes 46508f6c3df8SBarry Smith .seealso: SNESType, SNESCreate(), SNESDestroy(), SNESGetType(), SNESSetFromOptions() 4651435da068SBarry Smith 46529b94acceSBarry Smith @*/ 465319fd82e9SBarry Smith PetscErrorCode SNESSetType(SNES snes,SNESType type) 46549b94acceSBarry Smith { 4655dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 4656ace3abfcSBarry Smith PetscBool match; 46573a40ed3dSBarry Smith 46583a40ed3dSBarry Smith PetscFunctionBegin; 46590700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 46604482741eSBarry Smith PetscValidCharPointer(type,2); 466182bf6240SBarry Smith 4662251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 46630f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 466492ff6ae8SBarry Smith 46651c9cd337SJed Brown ierr = PetscFunctionListFind(SNESList,type,&r);CHKERRQ(ierr); 4666e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 466775396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 4668b5c23020SJed Brown if (snes->ops->destroy) { 4669b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 46700298fd71SBarry Smith snes->ops->destroy = NULL; 4671b5c23020SJed Brown } 467275396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 46739e5d0892SLisandro Dalcin snes->ops->setup = NULL; 46749e5d0892SLisandro Dalcin snes->ops->solve = NULL; 46759e5d0892SLisandro Dalcin snes->ops->view = NULL; 46769e5d0892SLisandro Dalcin snes->ops->setfromoptions = NULL; 46779e5d0892SLisandro Dalcin snes->ops->destroy = NULL; 46787fe760d5SStefano Zampini 46797fe760d5SStefano Zampini /* It may happen the user has customized the line search before calling SNESSetType */ 46807fe760d5SStefano Zampini if (((PetscObject)snes)->type_name) { 4681d8d34be6SBarry Smith ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 46827fe760d5SStefano Zampini } 46837fe760d5SStefano Zampini 468475396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 468575396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 4686f5af7f23SKarl Rupp 4687454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 468803bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 46893a40ed3dSBarry Smith PetscFunctionReturn(0); 46909b94acceSBarry Smith } 46919b94acceSBarry Smith 46929b94acceSBarry Smith /*@C 46939a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 46949b94acceSBarry Smith 4695c7afd0dbSLois Curfman McInnes Not Collective 4696c7afd0dbSLois Curfman McInnes 46979b94acceSBarry Smith Input Parameter: 46984b0e389bSBarry Smith . snes - nonlinear solver context 46999b94acceSBarry Smith 47009b94acceSBarry Smith Output Parameter: 47013a7fca6bSBarry Smith . type - SNES method (a character string) 47029b94acceSBarry Smith 470336851e7fSLois Curfman McInnes Level: intermediate 470436851e7fSLois Curfman McInnes 47059b94acceSBarry Smith @*/ 470619fd82e9SBarry Smith PetscErrorCode SNESGetType(SNES snes,SNESType *type) 47079b94acceSBarry Smith { 47083a40ed3dSBarry Smith PetscFunctionBegin; 47090700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 47104482741eSBarry Smith PetscValidPointer(type,2); 47117adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 47123a40ed3dSBarry Smith PetscFunctionReturn(0); 47139b94acceSBarry Smith } 47149b94acceSBarry Smith 47153cd8a7caSMatthew G. Knepley /*@ 47163cd8a7caSMatthew G. Knepley SNESSetSolution - Sets the solution vector for use by the SNES routines. 47173cd8a7caSMatthew G. Knepley 4718d083f849SBarry Smith Logically Collective on SNES 47193cd8a7caSMatthew G. Knepley 47203cd8a7caSMatthew G. Knepley Input Parameters: 47213cd8a7caSMatthew G. Knepley + snes - the SNES context obtained from SNESCreate() 47223cd8a7caSMatthew G. Knepley - u - the solution vector 47233cd8a7caSMatthew G. Knepley 47243cd8a7caSMatthew G. Knepley Level: beginner 47253cd8a7caSMatthew G. Knepley 47263cd8a7caSMatthew G. Knepley @*/ 47273cd8a7caSMatthew G. Knepley PetscErrorCode SNESSetSolution(SNES snes, Vec u) 47283cd8a7caSMatthew G. Knepley { 47293cd8a7caSMatthew G. Knepley DM dm; 47303cd8a7caSMatthew G. Knepley PetscErrorCode ierr; 47313cd8a7caSMatthew G. Knepley 47323cd8a7caSMatthew G. Knepley PetscFunctionBegin; 47333cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 47343cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 47353cd8a7caSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) u);CHKERRQ(ierr); 47363cd8a7caSMatthew G. Knepley ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 47373cd8a7caSMatthew G. Knepley 47383cd8a7caSMatthew G. Knepley snes->vec_sol = u; 47393cd8a7caSMatthew G. Knepley 47403cd8a7caSMatthew G. Knepley ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 47413cd8a7caSMatthew G. Knepley ierr = DMShellSetGlobalVector(dm, u);CHKERRQ(ierr); 47423cd8a7caSMatthew G. Knepley PetscFunctionReturn(0); 47433cd8a7caSMatthew G. Knepley } 47443cd8a7caSMatthew G. Knepley 474552baeb72SSatish Balay /*@ 47469b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 4747c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 47489b94acceSBarry Smith 4749c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 4750c7afd0dbSLois Curfman McInnes 47519b94acceSBarry Smith Input Parameter: 47529b94acceSBarry Smith . snes - the SNES context 47539b94acceSBarry Smith 47549b94acceSBarry Smith Output Parameter: 47559b94acceSBarry Smith . x - the solution 47569b94acceSBarry Smith 475770e92668SMatthew Knepley Level: intermediate 475836851e7fSLois Curfman McInnes 475985385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 47609b94acceSBarry Smith @*/ 47617087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 47629b94acceSBarry Smith { 47633a40ed3dSBarry Smith PetscFunctionBegin; 47640700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 47654482741eSBarry Smith PetscValidPointer(x,2); 476685385478SLisandro Dalcin *x = snes->vec_sol; 476770e92668SMatthew Knepley PetscFunctionReturn(0); 476870e92668SMatthew Knepley } 476970e92668SMatthew Knepley 477052baeb72SSatish Balay /*@ 47719b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 47729b94acceSBarry Smith stored. 47739b94acceSBarry Smith 4774c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 4775c7afd0dbSLois Curfman McInnes 47769b94acceSBarry Smith Input Parameter: 47779b94acceSBarry Smith . snes - the SNES context 47789b94acceSBarry Smith 47799b94acceSBarry Smith Output Parameter: 47809b94acceSBarry Smith . x - the solution update 47819b94acceSBarry Smith 478236851e7fSLois Curfman McInnes Level: advanced 478336851e7fSLois Curfman McInnes 478485385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 47859b94acceSBarry Smith @*/ 47867087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 47879b94acceSBarry Smith { 47883a40ed3dSBarry Smith PetscFunctionBegin; 47890700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 47904482741eSBarry Smith PetscValidPointer(x,2); 479185385478SLisandro Dalcin *x = snes->vec_sol_update; 47923a40ed3dSBarry Smith PetscFunctionReturn(0); 47939b94acceSBarry Smith } 47949b94acceSBarry Smith 47959b94acceSBarry Smith /*@C 47963638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 47979b94acceSBarry Smith 4798a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 4799c7afd0dbSLois Curfman McInnes 48009b94acceSBarry Smith Input Parameter: 48019b94acceSBarry Smith . snes - the SNES context 48029b94acceSBarry Smith 48039b94acceSBarry Smith Output Parameter: 48040298fd71SBarry Smith + r - the vector that is used to store residuals (or NULL if you don't want it) 4805f8b49ee9SBarry Smith . f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details 48060298fd71SBarry Smith - ctx - the function context (or NULL if you don't want it) 48079b94acceSBarry Smith 480836851e7fSLois Curfman McInnes Level: advanced 480936851e7fSLois Curfman McInnes 481004edfde5SBarry Smith Notes: The vector r DOES NOT, in general contain the current value of the SNES nonlinear function 481104edfde5SBarry Smith 4812bf388a1fSBarry Smith .seealso: SNESSetFunction(), SNESGetSolution(), SNESFunction 48139b94acceSBarry Smith @*/ 4814f8b49ee9SBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx) 48159b94acceSBarry Smith { 4816a63bb30eSJed Brown PetscErrorCode ierr; 48176cab3a1bSJed Brown DM dm; 4818a63bb30eSJed Brown 48193a40ed3dSBarry Smith PetscFunctionBegin; 48200700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4821a63bb30eSJed Brown if (r) { 4822a63bb30eSJed Brown if (!snes->vec_func) { 4823a63bb30eSJed Brown if (snes->vec_rhs) { 4824a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 4825a63bb30eSJed Brown } else if (snes->vec_sol) { 4826a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 4827a63bb30eSJed Brown } else if (snes->dm) { 4828a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 4829a63bb30eSJed Brown } 4830a63bb30eSJed Brown } 4831a63bb30eSJed Brown *r = snes->vec_func; 4832a63bb30eSJed Brown } 48336cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4834f8b49ee9SBarry Smith ierr = DMSNESGetFunction(dm,f,ctx);CHKERRQ(ierr); 48353a40ed3dSBarry Smith PetscFunctionReturn(0); 48369b94acceSBarry Smith } 48379b94acceSBarry Smith 4838c79ef259SPeter Brune /*@C 4839be95d8f1SBarry Smith SNESGetNGS - Returns the NGS function and context. 4840c79ef259SPeter Brune 4841c79ef259SPeter Brune Input Parameter: 4842c79ef259SPeter Brune . snes - the SNES context 4843c79ef259SPeter Brune 4844c79ef259SPeter Brune Output Parameter: 4845be95d8f1SBarry Smith + f - the function (or NULL) see SNESNGSFunction for details 48460298fd71SBarry Smith - ctx - the function context (or NULL) 4847c79ef259SPeter Brune 4848c79ef259SPeter Brune Level: advanced 4849c79ef259SPeter Brune 4850be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESGetFunction() 4851c79ef259SPeter Brune @*/ 4852c79ef259SPeter Brune 4853be95d8f1SBarry Smith PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx) 4854646217ecSPeter Brune { 48556cab3a1bSJed Brown PetscErrorCode ierr; 48566cab3a1bSJed Brown DM dm; 48576cab3a1bSJed Brown 4858646217ecSPeter Brune PetscFunctionBegin; 4859646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 48606cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4861be95d8f1SBarry Smith ierr = DMSNESGetNGS(dm,f,ctx);CHKERRQ(ierr); 4862646217ecSPeter Brune PetscFunctionReturn(0); 4863646217ecSPeter Brune } 4864646217ecSPeter Brune 48653c7409f5SSatish Balay /*@C 48663c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 4867d850072dSLois Curfman McInnes SNES options in the database. 48683c7409f5SSatish Balay 48693f9fe445SBarry Smith Logically Collective on SNES 4870fee21e36SBarry Smith 4871c7afd0dbSLois Curfman McInnes Input Parameter: 4872c7afd0dbSLois Curfman McInnes + snes - the SNES context 4873c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 4874c7afd0dbSLois Curfman McInnes 4875d850072dSLois Curfman McInnes Notes: 4876a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 4877c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 4878d850072dSLois Curfman McInnes 487936851e7fSLois Curfman McInnes Level: advanced 488036851e7fSLois Curfman McInnes 4881a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 48823c7409f5SSatish Balay @*/ 48837087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 48843c7409f5SSatish Balay { 4885dfbe8321SBarry Smith PetscErrorCode ierr; 48863c7409f5SSatish Balay 48873a40ed3dSBarry Smith PetscFunctionBegin; 48880700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4889639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 48901cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 489135f5d045SPeter Brune if (snes->linesearch) { 48927601faf0SJed Brown ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 489308b6c495SPeter Brune ierr = PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 489435f5d045SPeter Brune } 489535f5d045SPeter Brune ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 48963a40ed3dSBarry Smith PetscFunctionReturn(0); 48973c7409f5SSatish Balay } 48983c7409f5SSatish Balay 48993c7409f5SSatish Balay /*@C 4900f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 4901d850072dSLois Curfman McInnes SNES options in the database. 49023c7409f5SSatish Balay 49033f9fe445SBarry Smith Logically Collective on SNES 4904fee21e36SBarry Smith 4905c7afd0dbSLois Curfman McInnes Input Parameters: 4906c7afd0dbSLois Curfman McInnes + snes - the SNES context 4907c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 4908c7afd0dbSLois Curfman McInnes 4909d850072dSLois Curfman McInnes Notes: 4910a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 4911c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 4912d850072dSLois Curfman McInnes 491336851e7fSLois Curfman McInnes Level: advanced 491436851e7fSLois Curfman McInnes 4915a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 49163c7409f5SSatish Balay @*/ 49177087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 49183c7409f5SSatish Balay { 4919dfbe8321SBarry Smith PetscErrorCode ierr; 49203c7409f5SSatish Balay 49213a40ed3dSBarry Smith PetscFunctionBegin; 49220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4923639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 49241cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 492535f5d045SPeter Brune if (snes->linesearch) { 49267601faf0SJed Brown ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 492708b6c495SPeter Brune ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 492835f5d045SPeter Brune } 492935f5d045SPeter Brune ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 49303a40ed3dSBarry Smith PetscFunctionReturn(0); 49313c7409f5SSatish Balay } 49323c7409f5SSatish Balay 49339ab63eb5SSatish Balay /*@C 49343c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 49353c7409f5SSatish Balay SNES options in the database. 49363c7409f5SSatish Balay 4937c7afd0dbSLois Curfman McInnes Not Collective 4938c7afd0dbSLois Curfman McInnes 49393c7409f5SSatish Balay Input Parameter: 49403c7409f5SSatish Balay . snes - the SNES context 49413c7409f5SSatish Balay 49423c7409f5SSatish Balay Output Parameter: 49433c7409f5SSatish Balay . prefix - pointer to the prefix string used 49443c7409f5SSatish Balay 494595452b02SPatrick Sanan Notes: 494695452b02SPatrick Sanan On the fortran side, the user should pass in a string 'prefix' of 49479ab63eb5SSatish Balay sufficient length to hold the prefix. 49489ab63eb5SSatish Balay 494936851e7fSLois Curfman McInnes Level: advanced 495036851e7fSLois Curfman McInnes 4951a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 49523c7409f5SSatish Balay @*/ 49537087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 49543c7409f5SSatish Balay { 4955dfbe8321SBarry Smith PetscErrorCode ierr; 49563c7409f5SSatish Balay 49573a40ed3dSBarry Smith PetscFunctionBegin; 49580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4959639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 49603a40ed3dSBarry Smith PetscFunctionReturn(0); 49613c7409f5SSatish Balay } 49623c7409f5SSatish Balay 4963b2002411SLois Curfman McInnes 49643cea93caSBarry Smith /*@C 49651c84c290SBarry Smith SNESRegister - Adds a method to the nonlinear solver package. 49661c84c290SBarry Smith 49671c84c290SBarry Smith Not collective 49681c84c290SBarry Smith 49691c84c290SBarry Smith Input Parameters: 49701c84c290SBarry Smith + name_solver - name of a new user-defined solver 49711c84c290SBarry Smith - routine_create - routine to create method context 49721c84c290SBarry Smith 49731c84c290SBarry Smith Notes: 49741c84c290SBarry Smith SNESRegister() may be called multiple times to add several user-defined solvers. 49751c84c290SBarry Smith 49761c84c290SBarry Smith Sample usage: 49771c84c290SBarry Smith .vb 4978bdf89e91SBarry Smith SNESRegister("my_solver",MySolverCreate); 49791c84c290SBarry Smith .ve 49801c84c290SBarry Smith 49811c84c290SBarry Smith Then, your solver can be chosen with the procedural interface via 49821c84c290SBarry Smith $ SNESSetType(snes,"my_solver") 49831c84c290SBarry Smith or at runtime via the option 49841c84c290SBarry Smith $ -snes_type my_solver 49851c84c290SBarry Smith 49861c84c290SBarry Smith Level: advanced 49871c84c290SBarry Smith 49881c84c290SBarry Smith Note: If your function is not being put into a shared library then use SNESRegister() instead 49891c84c290SBarry Smith 49901c84c290SBarry Smith .seealso: SNESRegisterAll(), SNESRegisterDestroy() 49913cea93caSBarry Smith 49927f6c08e0SMatthew Knepley Level: advanced 49933cea93caSBarry Smith @*/ 4994bdf89e91SBarry Smith PetscErrorCode SNESRegister(const char sname[],PetscErrorCode (*function)(SNES)) 4995b2002411SLois Curfman McInnes { 4996dfbe8321SBarry Smith PetscErrorCode ierr; 4997b2002411SLois Curfman McInnes 4998b2002411SLois Curfman McInnes PetscFunctionBegin; 49991d36bdfdSBarry Smith ierr = SNESInitializePackage();CHKERRQ(ierr); 5000a240a19fSJed Brown ierr = PetscFunctionListAdd(&SNESList,sname,function);CHKERRQ(ierr); 5001b2002411SLois Curfman McInnes PetscFunctionReturn(0); 5002b2002411SLois Curfman McInnes } 5003da9b6338SBarry Smith 50047087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 5005da9b6338SBarry Smith { 5006dfbe8321SBarry Smith PetscErrorCode ierr; 500777431f27SBarry Smith PetscInt N,i,j; 5008da9b6338SBarry Smith Vec u,uh,fh; 5009da9b6338SBarry Smith PetscScalar value; 5010da9b6338SBarry Smith PetscReal norm; 5011da9b6338SBarry Smith 5012da9b6338SBarry Smith PetscFunctionBegin; 5013da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 5014da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 5015da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 5016da9b6338SBarry Smith 5017da9b6338SBarry Smith /* currently only works for sequential */ 5018ea13f565SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"Testing FormFunction() for local min\n");CHKERRQ(ierr); 5019da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 5020da9b6338SBarry Smith for (i=0; i<N; i++) { 5021da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 5022ea13f565SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"i = %D\n",i);CHKERRQ(ierr); 5023da9b6338SBarry Smith for (j=-10; j<11; j++) { 50248b49ba18SBarry Smith value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0); 5025da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 50263ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 5027da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 5028ea13f565SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)snes)," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 5029da9b6338SBarry Smith value = -value; 5030da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 5031da9b6338SBarry Smith } 5032da9b6338SBarry Smith } 50336bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 50346bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 5035da9b6338SBarry Smith PetscFunctionReturn(0); 5036da9b6338SBarry Smith } 503771f87433Sdalcinl 503871f87433Sdalcinl /*@ 5039fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 504071f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 504171f87433Sdalcinl Newton method. 504271f87433Sdalcinl 50433f9fe445SBarry Smith Logically Collective on SNES 504471f87433Sdalcinl 504571f87433Sdalcinl Input Parameters: 504671f87433Sdalcinl + snes - SNES context 504771f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 504871f87433Sdalcinl 504964ba62caSBarry Smith Options Database: 505064ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 505164ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 505264ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 505364ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 505464ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 505564ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 505664ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 505764ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 505864ba62caSBarry Smith 505971f87433Sdalcinl Notes: 506071f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 506171f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 506271f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 506371f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 506471f87433Sdalcinl solver. 506571f87433Sdalcinl 506671f87433Sdalcinl Level: advanced 506771f87433Sdalcinl 506871f87433Sdalcinl Reference: 506971f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 507071f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 507171f87433Sdalcinl 5072fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 507371f87433Sdalcinl @*/ 50747087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 507571f87433Sdalcinl { 507671f87433Sdalcinl PetscFunctionBegin; 50770700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5078acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 507971f87433Sdalcinl snes->ksp_ewconv = flag; 508071f87433Sdalcinl PetscFunctionReturn(0); 508171f87433Sdalcinl } 508271f87433Sdalcinl 508371f87433Sdalcinl /*@ 5084fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 508571f87433Sdalcinl for computing relative tolerance for linear solvers within an 508671f87433Sdalcinl inexact Newton method. 508771f87433Sdalcinl 508871f87433Sdalcinl Not Collective 508971f87433Sdalcinl 509071f87433Sdalcinl Input Parameter: 509171f87433Sdalcinl . snes - SNES context 509271f87433Sdalcinl 509371f87433Sdalcinl Output Parameter: 509471f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 509571f87433Sdalcinl 509671f87433Sdalcinl Notes: 509771f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 509871f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 509971f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 510071f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 510171f87433Sdalcinl solver. 510271f87433Sdalcinl 510371f87433Sdalcinl Level: advanced 510471f87433Sdalcinl 510571f87433Sdalcinl Reference: 510671f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 510771f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 510871f87433Sdalcinl 5109fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 511071f87433Sdalcinl @*/ 51117087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 511271f87433Sdalcinl { 511371f87433Sdalcinl PetscFunctionBegin; 51140700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5115534a8f05SLisandro Dalcin PetscValidBoolPointer(flag,2); 511671f87433Sdalcinl *flag = snes->ksp_ewconv; 511771f87433Sdalcinl PetscFunctionReturn(0); 511871f87433Sdalcinl } 511971f87433Sdalcinl 512071f87433Sdalcinl /*@ 5121fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 512271f87433Sdalcinl convergence criteria for the linear solvers within an inexact 512371f87433Sdalcinl Newton method. 512471f87433Sdalcinl 51253f9fe445SBarry Smith Logically Collective on SNES 512671f87433Sdalcinl 512771f87433Sdalcinl Input Parameters: 512871f87433Sdalcinl + snes - SNES context 512971f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 513071f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 513171f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 513271f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 513371f87433Sdalcinl (0 <= gamma2 <= 1) 513471f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 513571f87433Sdalcinl . alpha2 - power for safeguard 513671f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 513771f87433Sdalcinl 513871f87433Sdalcinl Note: 513971f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 514071f87433Sdalcinl 514171f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 514271f87433Sdalcinl 514371f87433Sdalcinl Level: advanced 514471f87433Sdalcinl 514571f87433Sdalcinl Reference: 514671f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 514771f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 514871f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 514971f87433Sdalcinl 5150fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 515171f87433Sdalcinl @*/ 5152f5af7f23SKarl Rupp PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 515371f87433Sdalcinl { 5154fa9f3622SBarry Smith SNESKSPEW *kctx; 51555fd66863SKarl Rupp 515671f87433Sdalcinl PetscFunctionBegin; 51570700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5158fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 5159e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 5160c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 5161c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 5162c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 5163c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 5164c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 5165c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 5166c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 516771f87433Sdalcinl 516871f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 516971f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 517071f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 517171f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 517271f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 517371f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 517471f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 517571f87433Sdalcinl 5176f23aa3ddSBarry 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); 517757622a8eSBarry 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); 517857622a8eSBarry 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); 517957622a8eSBarry 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); 518057622a8eSBarry 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); 518157622a8eSBarry 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); 518271f87433Sdalcinl PetscFunctionReturn(0); 518371f87433Sdalcinl } 518471f87433Sdalcinl 518571f87433Sdalcinl /*@ 5186fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 518771f87433Sdalcinl convergence criteria for the linear solvers within an inexact 518871f87433Sdalcinl Newton method. 518971f87433Sdalcinl 519071f87433Sdalcinl Not Collective 519171f87433Sdalcinl 519271f87433Sdalcinl Input Parameters: 519371f87433Sdalcinl snes - SNES context 519471f87433Sdalcinl 519571f87433Sdalcinl Output Parameters: 519671f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 519771f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 519871f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 5199bf388a1fSBarry Smith . gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1) 520071f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 520171f87433Sdalcinl . alpha2 - power for safeguard 520271f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 520371f87433Sdalcinl 520471f87433Sdalcinl Level: advanced 520571f87433Sdalcinl 5206fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 520771f87433Sdalcinl @*/ 5208bf388a1fSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 520971f87433Sdalcinl { 5210fa9f3622SBarry Smith SNESKSPEW *kctx; 52115fd66863SKarl Rupp 521271f87433Sdalcinl PetscFunctionBegin; 52130700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5214fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 5215e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 521671f87433Sdalcinl if (version) *version = kctx->version; 521771f87433Sdalcinl if (rtol_0) *rtol_0 = kctx->rtol_0; 521871f87433Sdalcinl if (rtol_max) *rtol_max = kctx->rtol_max; 521971f87433Sdalcinl if (gamma) *gamma = kctx->gamma; 522071f87433Sdalcinl if (alpha) *alpha = kctx->alpha; 522171f87433Sdalcinl if (alpha2) *alpha2 = kctx->alpha2; 522271f87433Sdalcinl if (threshold) *threshold = kctx->threshold; 522371f87433Sdalcinl PetscFunctionReturn(0); 522471f87433Sdalcinl } 522571f87433Sdalcinl 5226d5378b5fSDmitry Karpeev PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 522771f87433Sdalcinl { 522871f87433Sdalcinl PetscErrorCode ierr; 5229fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 523071f87433Sdalcinl PetscReal rtol = PETSC_DEFAULT,stol; 523171f87433Sdalcinl 523271f87433Sdalcinl PetscFunctionBegin; 5233d4211eb9SBarry Smith if (!snes->ksp_ewconv) PetscFunctionReturn(0); 523430058271SDmitry Karpeev if (!snes->iter) { 523530058271SDmitry Karpeev rtol = kctx->rtol_0; /* first time in, so use the original user rtol */ 523630058271SDmitry Karpeev ierr = VecNorm(snes->vec_func,NORM_2,&kctx->norm_first);CHKERRQ(ierr); 523730058271SDmitry Karpeev } 5238f5af7f23SKarl Rupp else { 523971f87433Sdalcinl if (kctx->version == 1) { 524071f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 524171f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 524285ec1a3cSBarry Smith stol = PetscPowReal(kctx->rtol_last,kctx->alpha2); 524371f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 524471f87433Sdalcinl } else if (kctx->version == 2) { 524585ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 524685ec1a3cSBarry Smith stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha); 524771f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 524871f87433Sdalcinl } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */ 524985ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 525071f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 525185ec1a3cSBarry Smith stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha); 525271f87433Sdalcinl stol = PetscMax(rtol,stol); 525371f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 525471f87433Sdalcinl /* safeguard: avoid oversolving */ 525530058271SDmitry Karpeev stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm; 525671f87433Sdalcinl stol = PetscMax(rtol,stol); 525771f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 5258e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 525971f87433Sdalcinl } 526071f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 526171f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 526271f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 526357622a8eSBarry Smith ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol);CHKERRQ(ierr); 526471f87433Sdalcinl PetscFunctionReturn(0); 526571f87433Sdalcinl } 526671f87433Sdalcinl 5267d5378b5fSDmitry Karpeev PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 526871f87433Sdalcinl { 526971f87433Sdalcinl PetscErrorCode ierr; 5270fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 527171f87433Sdalcinl PCSide pcside; 527271f87433Sdalcinl Vec lres; 527371f87433Sdalcinl 527471f87433Sdalcinl PetscFunctionBegin; 5275d4211eb9SBarry Smith if (!snes->ksp_ewconv) PetscFunctionReturn(0); 52769e5d0892SLisandro Dalcin ierr = KSPGetTolerances(ksp,&kctx->rtol_last,NULL,NULL,NULL);CHKERRQ(ierr); 527771dbe336SPeter Brune kctx->norm_last = snes->norm; 527871f87433Sdalcinl if (kctx->version == 1) { 52794f00ce20SMatthew G. Knepley PC pc; 52804f00ce20SMatthew G. Knepley PetscBool isNone; 52814f00ce20SMatthew G. Knepley 52824f00ce20SMatthew G. Knepley ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr); 52834f00ce20SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) pc, PCNONE, &isNone);CHKERRQ(ierr); 5284b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 52854f00ce20SMatthew G. Knepley if (pcside == PC_RIGHT || isNone) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 528671f87433Sdalcinl /* KSP residual is true linear residual */ 528771f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 528871f87433Sdalcinl } else { 528971f87433Sdalcinl /* KSP residual is preconditioned residual */ 529071f87433Sdalcinl /* compute true linear residual norm */ 529171f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 529271f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 529371f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 529471f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 52956bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 529671f87433Sdalcinl } 529771f87433Sdalcinl } 529871f87433Sdalcinl PetscFunctionReturn(0); 529971f87433Sdalcinl } 530071f87433Sdalcinl 5301d4211eb9SBarry Smith /*@ 5302d4211eb9SBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 5303d4211eb9SBarry Smith 5304d4211eb9SBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 5305d4211eb9SBarry Smith 5306d4211eb9SBarry Smith Input Parameter: 5307d4211eb9SBarry Smith . snes - the SNES context 5308d4211eb9SBarry Smith 5309d4211eb9SBarry Smith Output Parameter: 5310d4211eb9SBarry Smith . ksp - the KSP context 5311d4211eb9SBarry Smith 5312d4211eb9SBarry Smith Notes: 5313d4211eb9SBarry Smith The user can then directly manipulate the KSP context to set various 5314d4211eb9SBarry Smith options, etc. Likewise, the user can then extract and manipulate the 5315d4211eb9SBarry Smith PC contexts as well. 5316d4211eb9SBarry Smith 5317d4211eb9SBarry Smith Level: beginner 5318d4211eb9SBarry Smith 5319d4211eb9SBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 5320d4211eb9SBarry Smith @*/ 5321d4211eb9SBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 532271f87433Sdalcinl { 532371f87433Sdalcinl PetscErrorCode ierr; 532471f87433Sdalcinl 532571f87433Sdalcinl PetscFunctionBegin; 5326d4211eb9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5327d4211eb9SBarry Smith PetscValidPointer(ksp,2); 5328d4211eb9SBarry Smith 5329d4211eb9SBarry Smith if (!snes->ksp) { 5330a5c2985bSBarry Smith PetscBool monitor = PETSC_FALSE; 5331a5c2985bSBarry Smith 5332d4211eb9SBarry Smith ierr = KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp);CHKERRQ(ierr); 5333d4211eb9SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 53343bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp);CHKERRQ(ierr); 5335d4211eb9SBarry Smith 5336d5378b5fSDmitry Karpeev ierr = KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes);CHKERRQ(ierr); 5337d5378b5fSDmitry Karpeev ierr = KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes);CHKERRQ(ierr); 5338a5c2985bSBarry Smith 5339c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes",&monitor,NULL);CHKERRQ(ierr); 5340a5c2985bSBarry Smith if (monitor) { 5341a5c2985bSBarry Smith ierr = KSPMonitorSet(snes->ksp,KSPMonitorSNES,snes,NULL);CHKERRQ(ierr); 5342a5c2985bSBarry Smith } 5343e5f7ee39SBarry Smith monitor = PETSC_FALSE; 5344c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes_lg",&monitor,NULL);CHKERRQ(ierr); 5345e5f7ee39SBarry Smith if (monitor) { 5346e5f7ee39SBarry Smith PetscObject *objs; 53478b0b5a47SLisandro Dalcin ierr = KSPMonitorSNESLGResidualNormCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,600,600,&objs);CHKERRQ(ierr); 5348e5f7ee39SBarry Smith objs[0] = (PetscObject) snes; 5349e5f7ee39SBarry Smith ierr = KSPMonitorSet(snes->ksp,(PetscErrorCode (*)(KSP,PetscInt,PetscReal,void*))KSPMonitorSNESLGResidualNorm,objs,(PetscErrorCode (*)(void**))KSPMonitorSNESLGResidualNormDestroy);CHKERRQ(ierr); 5350e5f7ee39SBarry Smith } 535116413a6aSBarry Smith ierr = PetscObjectSetOptions((PetscObject)snes->ksp,((PetscObject)snes)->options);CHKERRQ(ierr); 5352d4211eb9SBarry Smith } 5353d4211eb9SBarry Smith *ksp = snes->ksp; 535471f87433Sdalcinl PetscFunctionReturn(0); 535571f87433Sdalcinl } 53566c699258SBarry Smith 5357d4211eb9SBarry Smith 5358af0996ceSBarry Smith #include <petsc/private/dmimpl.h> 53596c699258SBarry Smith /*@ 53602a808120SBarry Smith SNESSetDM - Sets the DM that may be used by some nonlinear solvers or their underlying preconditioners 53616c699258SBarry Smith 53623f9fe445SBarry Smith Logically Collective on SNES 53636c699258SBarry Smith 53646c699258SBarry Smith Input Parameters: 53652a808120SBarry Smith + snes - the nonlinear solver context 53662a808120SBarry Smith - dm - the dm, cannot be NULL 53676c699258SBarry Smith 5368e03a659cSJed Brown Notes: 5369e03a659cSJed Brown A DM can only be used for solving one problem at a time because information about the problem is stored on the DM, 5370e03a659cSJed Brown even when not using interfaces like DMSNESSetFunction(). Use DMClone() to get a distinct DM when solving different 5371e03a659cSJed Brown problems using the same function space. 5372e03a659cSJed Brown 53736c699258SBarry Smith Level: intermediate 53746c699258SBarry Smith 53754c2026ceSFande Kong .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 53766c699258SBarry Smith @*/ 53777087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 53786c699258SBarry Smith { 53796c699258SBarry Smith PetscErrorCode ierr; 5380345fed2cSBarry Smith KSP ksp; 5381942e3340SBarry Smith DMSNES sdm; 53826c699258SBarry Smith 53836c699258SBarry Smith PetscFunctionBegin; 53840700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 53852a808120SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,2); 53862a808120SBarry Smith ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 5387942e3340SBarry Smith if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */ 538851f4b3c7SToby Isaac if (snes->dm->dmsnes && !dm->dmsnes) { 5389942e3340SBarry Smith ierr = DMCopyDMSNES(snes->dm,dm);CHKERRQ(ierr); 5390942e3340SBarry Smith ierr = DMGetDMSNES(snes->dm,&sdm);CHKERRQ(ierr); 5391f5af7f23SKarl Rupp if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */ 53926cab3a1bSJed Brown } 5393dc822a44SJed Brown ierr = DMCoarsenHookRemove(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 53946bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 53956cab3a1bSJed Brown } 53966c699258SBarry Smith snes->dm = dm; 5397116d1032SJed Brown snes->dmAuto = PETSC_FALSE; 5398f5af7f23SKarl Rupp 5399345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 5400345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 5401f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 5402efd4aadfSBarry Smith if (snes->npc) { 5403efd4aadfSBarry Smith ierr = SNESSetDM(snes->npc, snes->dm);CHKERRQ(ierr); 5404efd4aadfSBarry Smith ierr = SNESSetNPCSide(snes,snes->npcside);CHKERRQ(ierr); 54052c155ee1SBarry Smith } 54066c699258SBarry Smith PetscFunctionReturn(0); 54076c699258SBarry Smith } 54086c699258SBarry Smith 54096c699258SBarry Smith /*@ 54106c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 54116c699258SBarry Smith 54123f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 54136c699258SBarry Smith 54146c699258SBarry Smith Input Parameter: 54156c699258SBarry Smith . snes - the preconditioner context 54166c699258SBarry Smith 54176c699258SBarry Smith Output Parameter: 54186c699258SBarry Smith . dm - the dm 54196c699258SBarry Smith 54206c699258SBarry Smith Level: intermediate 54216c699258SBarry Smith 54224c2026ceSFande Kong .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 54236c699258SBarry Smith @*/ 54247087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 54256c699258SBarry Smith { 54266cab3a1bSJed Brown PetscErrorCode ierr; 54276cab3a1bSJed Brown 54286c699258SBarry Smith PetscFunctionBegin; 54290700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 54306cab3a1bSJed Brown if (!snes->dm) { 5431ce94432eSBarry Smith ierr = DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm);CHKERRQ(ierr); 5432116d1032SJed Brown snes->dmAuto = PETSC_TRUE; 54336cab3a1bSJed Brown } 54346c699258SBarry Smith *dm = snes->dm; 54356c699258SBarry Smith PetscFunctionReturn(0); 54366c699258SBarry Smith } 54370807856dSBarry Smith 543831823bd8SMatthew G Knepley /*@ 5439be95d8f1SBarry Smith SNESSetNPC - Sets the nonlinear preconditioner to be used. 544031823bd8SMatthew G Knepley 544131823bd8SMatthew G Knepley Collective on SNES 544231823bd8SMatthew G Knepley 544331823bd8SMatthew G Knepley Input Parameters: 544431823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 544531823bd8SMatthew G Knepley - pc - the preconditioner object 544631823bd8SMatthew G Knepley 544731823bd8SMatthew G Knepley Notes: 5448be95d8f1SBarry Smith Use SNESGetNPC() to retrieve the preconditioner context (for example, 544931823bd8SMatthew G Knepley to configure it using the API). 545031823bd8SMatthew G Knepley 545131823bd8SMatthew G Knepley Level: developer 545231823bd8SMatthew G Knepley 54533ad1a0b9SPatrick Farrell .seealso: SNESGetNPC(), SNESHasNPC() 545431823bd8SMatthew G Knepley @*/ 5455be95d8f1SBarry Smith PetscErrorCode SNESSetNPC(SNES snes, SNES pc) 545631823bd8SMatthew G Knepley { 545731823bd8SMatthew G Knepley PetscErrorCode ierr; 545831823bd8SMatthew G Knepley 545931823bd8SMatthew G Knepley PetscFunctionBegin; 546031823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 546131823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 546231823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 546331823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 5464efd4aadfSBarry Smith ierr = SNESDestroy(&snes->npc);CHKERRQ(ierr); 5465efd4aadfSBarry Smith snes->npc = pc; 5466efd4aadfSBarry Smith ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->npc);CHKERRQ(ierr); 546731823bd8SMatthew G Knepley PetscFunctionReturn(0); 546831823bd8SMatthew G Knepley } 546931823bd8SMatthew G Knepley 547031823bd8SMatthew G Knepley /*@ 5471be95d8f1SBarry Smith SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver. 547231823bd8SMatthew G Knepley 5473951fe5abSBarry Smith Not Collective; but any changes to the obtained SNES object must be applied collectively 547431823bd8SMatthew G Knepley 547531823bd8SMatthew G Knepley Input Parameter: 547631823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 547731823bd8SMatthew G Knepley 547831823bd8SMatthew G Knepley Output Parameter: 547931823bd8SMatthew G Knepley . pc - preconditioner context 548031823bd8SMatthew G Knepley 5481b5badacbSBarry Smith Options Database: 5482b5badacbSBarry Smith . -npc_snes_type <type> - set the type of the SNES to use as the nonlinear preconditioner 5483b5badacbSBarry Smith 548495452b02SPatrick Sanan Notes: 5485b5badacbSBarry Smith If a SNES was previously set with SNESSetNPC() then that SNES is returned, otherwise a new SNES object is created. 5486be95d8f1SBarry Smith 5487951fe5abSBarry Smith The (preconditioner) SNES returned automatically inherits the same nonlinear function and Jacobian supplied to the original 5488951fe5abSBarry Smith SNES during SNESSetUp() 5489951fe5abSBarry Smith 549031823bd8SMatthew G Knepley Level: developer 549131823bd8SMatthew G Knepley 5492951fe5abSBarry Smith .seealso: SNESSetNPC(), SNESHasNPC(), SNES, SNESCreate() 549331823bd8SMatthew G Knepley @*/ 5494be95d8f1SBarry Smith PetscErrorCode SNESGetNPC(SNES snes, SNES *pc) 549531823bd8SMatthew G Knepley { 549631823bd8SMatthew G Knepley PetscErrorCode ierr; 5497a64e098fSPeter Brune const char *optionsprefix; 549831823bd8SMatthew G Knepley 549931823bd8SMatthew G Knepley PetscFunctionBegin; 550031823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 550131823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 5502efd4aadfSBarry Smith if (!snes->npc) { 5503efd4aadfSBarry Smith ierr = SNESCreate(PetscObjectComm((PetscObject)snes),&snes->npc);CHKERRQ(ierr); 5504efd4aadfSBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->npc,(PetscObject)snes,1);CHKERRQ(ierr); 5505efd4aadfSBarry Smith ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr); 5506a64e098fSPeter Brune ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr); 5507efd4aadfSBarry Smith ierr = SNESSetOptionsPrefix(snes->npc,optionsprefix);CHKERRQ(ierr); 5508efd4aadfSBarry Smith ierr = SNESAppendOptionsPrefix(snes->npc,"npc_");CHKERRQ(ierr); 5509efd4aadfSBarry Smith ierr = SNESSetCountersReset(snes->npc,PETSC_FALSE);CHKERRQ(ierr); 551031823bd8SMatthew G Knepley } 5511efd4aadfSBarry Smith *pc = snes->npc; 551231823bd8SMatthew G Knepley PetscFunctionReturn(0); 551331823bd8SMatthew G Knepley } 551431823bd8SMatthew G Knepley 55153ad1a0b9SPatrick Farrell /*@ 55163ad1a0b9SPatrick Farrell SNESHasNPC - Returns whether a nonlinear preconditioner exists 55173ad1a0b9SPatrick Farrell 55183ad1a0b9SPatrick Farrell Not Collective 55193ad1a0b9SPatrick Farrell 55203ad1a0b9SPatrick Farrell Input Parameter: 55213ad1a0b9SPatrick Farrell . snes - iterative context obtained from SNESCreate() 55223ad1a0b9SPatrick Farrell 55233ad1a0b9SPatrick Farrell Output Parameter: 55243ad1a0b9SPatrick Farrell . has_npc - whether the SNES has an NPC or not 55253ad1a0b9SPatrick Farrell 55263ad1a0b9SPatrick Farrell Level: developer 55273ad1a0b9SPatrick Farrell 55283ad1a0b9SPatrick Farrell .seealso: SNESSetNPC(), SNESGetNPC() 55293ad1a0b9SPatrick Farrell @*/ 55303ad1a0b9SPatrick Farrell PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc) 55313ad1a0b9SPatrick Farrell { 55323ad1a0b9SPatrick Farrell PetscFunctionBegin; 55333ad1a0b9SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5534efd4aadfSBarry Smith *has_npc = (PetscBool) (snes->npc ? PETSC_TRUE : PETSC_FALSE); 55353ad1a0b9SPatrick Farrell PetscFunctionReturn(0); 55363ad1a0b9SPatrick Farrell } 55373ad1a0b9SPatrick Farrell 5538c40d0f55SPeter Brune /*@ 5539be95d8f1SBarry Smith SNESSetNPCSide - Sets the preconditioning side. 5540c40d0f55SPeter Brune 5541c40d0f55SPeter Brune Logically Collective on SNES 5542c40d0f55SPeter Brune 5543c40d0f55SPeter Brune Input Parameter: 5544c40d0f55SPeter Brune . snes - iterative context obtained from SNESCreate() 5545c40d0f55SPeter Brune 5546c40d0f55SPeter Brune Output Parameter: 5547c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5548c40d0f55SPeter Brune .vb 55492d547940SBarry Smith PC_LEFT - left preconditioning 55502d547940SBarry Smith PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5551c40d0f55SPeter Brune .ve 5552c40d0f55SPeter Brune 5553c40d0f55SPeter Brune Options Database Keys: 5554c40d0f55SPeter Brune . -snes_pc_side <right,left> 5555c40d0f55SPeter Brune 555695452b02SPatrick Sanan Notes: 555795452b02SPatrick Sanan SNESNRICHARDSON and SNESNCG only support left preconditioning. 55582d547940SBarry Smith 5559c40d0f55SPeter Brune Level: intermediate 5560c40d0f55SPeter Brune 5561be95d8f1SBarry Smith .seealso: SNESGetNPCSide(), KSPSetPCSide() 5562c40d0f55SPeter Brune @*/ 5563be95d8f1SBarry Smith PetscErrorCode SNESSetNPCSide(SNES snes,PCSide side) 5564c40d0f55SPeter Brune { 5565c40d0f55SPeter Brune PetscFunctionBegin; 5566c40d0f55SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5567c40d0f55SPeter Brune PetscValidLogicalCollectiveEnum(snes,side,2); 5568efd4aadfSBarry Smith snes->npcside= side; 5569c40d0f55SPeter Brune PetscFunctionReturn(0); 5570c40d0f55SPeter Brune } 5571c40d0f55SPeter Brune 5572c40d0f55SPeter Brune /*@ 5573be95d8f1SBarry Smith SNESGetNPCSide - Gets the preconditioning side. 5574c40d0f55SPeter Brune 5575c40d0f55SPeter Brune Not Collective 5576c40d0f55SPeter Brune 5577c40d0f55SPeter Brune Input Parameter: 5578c40d0f55SPeter Brune . snes - iterative context obtained from SNESCreate() 5579c40d0f55SPeter Brune 5580c40d0f55SPeter Brune Output Parameter: 5581c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5582c40d0f55SPeter Brune .vb 55832d547940SBarry Smith PC_LEFT - left preconditioning 55842d547940SBarry Smith PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5585c40d0f55SPeter Brune .ve 5586c40d0f55SPeter Brune 5587c40d0f55SPeter Brune Level: intermediate 5588c40d0f55SPeter Brune 5589be95d8f1SBarry Smith .seealso: SNESSetNPCSide(), KSPGetPCSide() 5590c40d0f55SPeter Brune @*/ 5591be95d8f1SBarry Smith PetscErrorCode SNESGetNPCSide(SNES snes,PCSide *side) 5592c40d0f55SPeter Brune { 5593c40d0f55SPeter Brune PetscFunctionBegin; 5594c40d0f55SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5595c40d0f55SPeter Brune PetscValidPointer(side,2); 5596efd4aadfSBarry Smith *side = snes->npcside; 5597c40d0f55SPeter Brune PetscFunctionReturn(0); 5598c40d0f55SPeter Brune } 5599c40d0f55SPeter Brune 56009e764e56SPeter Brune /*@ 56017601faf0SJed Brown SNESSetLineSearch - Sets the linesearch on the SNES instance. 56029e764e56SPeter Brune 56039e764e56SPeter Brune Collective on SNES 56049e764e56SPeter Brune 56059e764e56SPeter Brune Input Parameters: 56069e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 56079e764e56SPeter Brune - linesearch - the linesearch object 56089e764e56SPeter Brune 56099e764e56SPeter Brune Notes: 56107601faf0SJed Brown Use SNESGetLineSearch() to retrieve the preconditioner context (for example, 56119e764e56SPeter Brune to configure it using the API). 56129e764e56SPeter Brune 56139e764e56SPeter Brune Level: developer 56149e764e56SPeter Brune 56157601faf0SJed Brown .seealso: SNESGetLineSearch() 56169e764e56SPeter Brune @*/ 56177601faf0SJed Brown PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch) 56189e764e56SPeter Brune { 56199e764e56SPeter Brune PetscErrorCode ierr; 56209e764e56SPeter Brune 56219e764e56SPeter Brune PetscFunctionBegin; 56229e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5623f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 56249e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 56259e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 5626f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 5627f5af7f23SKarl Rupp 56289e764e56SPeter Brune snes->linesearch = linesearch; 5629f5af7f23SKarl Rupp 56303bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr); 56319e764e56SPeter Brune PetscFunctionReturn(0); 56329e764e56SPeter Brune } 56339e764e56SPeter Brune 5634a34ceb2aSJed Brown /*@ 56357601faf0SJed Brown SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 56368141a3b9SPeter Brune or creates a default line search instance associated with the SNES and returns it. 56379e764e56SPeter Brune 56389e764e56SPeter Brune Not Collective 56399e764e56SPeter Brune 56409e764e56SPeter Brune Input Parameter: 56419e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 56429e764e56SPeter Brune 56439e764e56SPeter Brune Output Parameter: 56449e764e56SPeter Brune . linesearch - linesearch context 56459e764e56SPeter Brune 5646162e0bf5SPeter Brune Level: beginner 56479e764e56SPeter Brune 5648162e0bf5SPeter Brune .seealso: SNESSetLineSearch(), SNESLineSearchCreate() 56499e764e56SPeter Brune @*/ 56507601faf0SJed Brown PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch) 56519e764e56SPeter Brune { 56529e764e56SPeter Brune PetscErrorCode ierr; 56539e764e56SPeter Brune const char *optionsprefix; 56549e764e56SPeter Brune 56559e764e56SPeter Brune PetscFunctionBegin; 56569e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 56579e764e56SPeter Brune PetscValidPointer(linesearch, 2); 56589e764e56SPeter Brune if (!snes->linesearch) { 56599e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 566082f516ccSBarry Smith ierr = SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch);CHKERRQ(ierr); 5661f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 5662b1dca40bSPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 56639e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 56643bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr); 56659e764e56SPeter Brune } 56669e764e56SPeter Brune *linesearch = snes->linesearch; 56679e764e56SPeter Brune PetscFunctionReturn(0); 56689e764e56SPeter Brune } 5669