19b94acceSBarry Smith 2af0996ceSBarry Smith #include <petsc/private/snesimpl.h> /*I "petscsnes.h" I*/ 307475bc1SBarry Smith #include <petscdmshell.h> 4d96771aaSLisandro Dalcin #include <petscdraw.h> 59b94acceSBarry Smith 6ace3abfcSBarry Smith PetscBool SNESRegisterAllCalled = PETSC_FALSE; 70298fd71SBarry Smith PetscFunctionList SNESList = NULL; 88ba1e511SMatthew Knepley 98ba1e511SMatthew Knepley /* Logging support */ 1022c6f798SBarry Smith PetscClassId SNES_CLASSID, DMSNES_CLASSID; 1194db00ebSBarry Smith PetscLogEvent SNES_Solve, SNES_FunctionEval, SNES_JacobianEval, SNES_NGSEval, SNES_NGSFuncEval, SNES_NPCSolve, SNES_ObjectiveEval; 12a09944afSBarry Smith 13a09944afSBarry Smith #undef __FUNCT__ 14e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged" 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 .keywords: SNES, set, initial guess, nonzero 34e113a28aSBarry Smith 35e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 36e113a28aSBarry Smith @*/ 377087cfbeSBarry Smith PetscErrorCode SNESSetErrorIfNotConverged(SNES snes,PetscBool flg) 38e113a28aSBarry Smith { 39e113a28aSBarry Smith PetscFunctionBegin; 40e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 41acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flg,2); 42e113a28aSBarry Smith snes->errorifnotconverged = flg; 43e113a28aSBarry Smith PetscFunctionReturn(0); 44e113a28aSBarry Smith } 45e113a28aSBarry Smith 46e113a28aSBarry Smith #undef __FUNCT__ 47e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged" 48e113a28aSBarry Smith /*@ 49e113a28aSBarry Smith SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge? 50e113a28aSBarry Smith 51e113a28aSBarry Smith Not Collective 52e113a28aSBarry Smith 53e113a28aSBarry Smith Input Parameter: 54e113a28aSBarry Smith . snes - iterative context obtained from SNESCreate() 55e113a28aSBarry Smith 56e113a28aSBarry Smith Output Parameter: 57e113a28aSBarry Smith . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE 58e113a28aSBarry Smith 59e113a28aSBarry Smith Level: intermediate 60e113a28aSBarry Smith 61e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 62e113a28aSBarry Smith 63e113a28aSBarry Smith .seealso: SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 64e113a28aSBarry Smith @*/ 657087cfbeSBarry Smith PetscErrorCode SNESGetErrorIfNotConverged(SNES snes,PetscBool *flag) 66e113a28aSBarry Smith { 67e113a28aSBarry Smith PetscFunctionBegin; 68e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 69e113a28aSBarry Smith PetscValidPointer(flag,2); 70e113a28aSBarry Smith *flag = snes->errorifnotconverged; 71e113a28aSBarry Smith PetscFunctionReturn(0); 72e113a28aSBarry Smith } 73e113a28aSBarry Smith 74e113a28aSBarry Smith #undef __FUNCT__ 754936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError" 76e725d27bSBarry Smith /*@ 77bf388a1fSBarry Smith SNESSetFunctionDomainError - tells SNES that the input vector to your SNESFunction is not 784936397dSBarry Smith in the functions domain. For example, negative pressure. 794936397dSBarry Smith 803f9fe445SBarry Smith Logically Collective on SNES 814936397dSBarry Smith 824936397dSBarry Smith Input Parameters: 836a388c36SPeter Brune . snes - the SNES context 844936397dSBarry Smith 8528529972SSatish Balay Level: advanced 864936397dSBarry Smith 874936397dSBarry Smith .keywords: SNES, view 884936397dSBarry Smith 89bf388a1fSBarry Smith .seealso: SNESCreate(), SNESSetFunction(), SNESFunction 904936397dSBarry Smith @*/ 917087cfbeSBarry Smith PetscErrorCode SNESSetFunctionDomainError(SNES snes) 924936397dSBarry Smith { 934936397dSBarry Smith PetscFunctionBegin; 940700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 95422a814eSBarry Smith if (snes->errorifnotconverged) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"User code indicates input vector is not in the function domain"); 964936397dSBarry Smith snes->domainerror = PETSC_TRUE; 974936397dSBarry Smith PetscFunctionReturn(0); 984936397dSBarry Smith } 994936397dSBarry Smith 1006a388c36SPeter Brune #undef __FUNCT__ 1016a388c36SPeter Brune #define __FUNCT__ "SNESGetFunctionDomainError" 1026a388c36SPeter Brune /*@ 103c77b2880SPeter Brune SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction; 1046a388c36SPeter Brune 1056a388c36SPeter Brune Logically Collective on SNES 1066a388c36SPeter Brune 1076a388c36SPeter Brune Input Parameters: 1086a388c36SPeter Brune . snes - the SNES context 1096a388c36SPeter Brune 1106a388c36SPeter Brune Output Parameters: 111bf388a1fSBarry Smith . domainerror - Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise. 1126a388c36SPeter Brune 1136a388c36SPeter Brune Level: advanced 1146a388c36SPeter Brune 1156a388c36SPeter Brune .keywords: SNES, view 1166a388c36SPeter Brune 117bf388a1fSBarry Smith .seealso: SNESSetFunctionDomainError(), SNESComputeFunction() 1186a388c36SPeter Brune @*/ 1196a388c36SPeter Brune PetscErrorCode SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror) 1206a388c36SPeter Brune { 1216a388c36SPeter Brune PetscFunctionBegin; 1226a388c36SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1236a388c36SPeter Brune PetscValidPointer(domainerror, 2); 1246a388c36SPeter Brune *domainerror = snes->domainerror; 1256a388c36SPeter Brune PetscFunctionReturn(0); 1266a388c36SPeter Brune } 1276a388c36SPeter Brune 12855849f57SBarry Smith #undef __FUNCT__ 12955849f57SBarry Smith #define __FUNCT__ "SNESLoad" 13055849f57SBarry Smith /*@C 13155849f57SBarry Smith SNESLoad - Loads a SNES that has been stored in binary with SNESView(). 13255849f57SBarry Smith 13355849f57SBarry Smith Collective on PetscViewer 13455849f57SBarry Smith 13555849f57SBarry Smith Input Parameters: 13655849f57SBarry Smith + newdm - the newly loaded SNES, this needs to have been created with SNESCreate() or 13755849f57SBarry Smith some related function before a call to SNESLoad(). 13855849f57SBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() 13955849f57SBarry Smith 14055849f57SBarry Smith Level: intermediate 14155849f57SBarry Smith 14255849f57SBarry Smith Notes: 14355849f57SBarry Smith The type is determined by the data in the file, any type set into the SNES before this call is ignored. 14455849f57SBarry Smith 14555849f57SBarry Smith Notes for advanced users: 14655849f57SBarry Smith Most users should not need to know the details of the binary storage 14755849f57SBarry Smith format, since SNESLoad() and TSView() completely hide these details. 14855849f57SBarry Smith But for anyone who's interested, the standard binary matrix storage 14955849f57SBarry Smith format is 15055849f57SBarry Smith .vb 15155849f57SBarry Smith has not yet been determined 15255849f57SBarry Smith .ve 15355849f57SBarry Smith 15455849f57SBarry Smith .seealso: PetscViewerBinaryOpen(), SNESView(), MatLoad(), VecLoad() 15555849f57SBarry Smith @*/ 1562d53ad75SBarry Smith PetscErrorCode SNESLoad(SNES snes, PetscViewer viewer) 15755849f57SBarry Smith { 15855849f57SBarry Smith PetscErrorCode ierr; 15955849f57SBarry Smith PetscBool isbinary; 160060da220SMatthew G. Knepley PetscInt classid; 16155849f57SBarry Smith char type[256]; 16255849f57SBarry Smith KSP ksp; 1632d53ad75SBarry Smith DM dm; 1642d53ad75SBarry Smith DMSNES dmsnes; 16555849f57SBarry Smith 16655849f57SBarry Smith PetscFunctionBegin; 1672d53ad75SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16855849f57SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 16955849f57SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 17055849f57SBarry Smith if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 17155849f57SBarry Smith 172060da220SMatthew G. Knepley ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr); 173ce94432eSBarry Smith if (classid != SNES_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONG,"Not SNES next in file"); 174060da220SMatthew G. Knepley ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr); 1752d53ad75SBarry Smith ierr = SNESSetType(snes, type);CHKERRQ(ierr); 1762d53ad75SBarry Smith if (snes->ops->load) { 1772d53ad75SBarry Smith ierr = (*snes->ops->load)(snes,viewer);CHKERRQ(ierr); 178f2c2a1b9SBarry Smith } 1792d53ad75SBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1802d53ad75SBarry Smith ierr = DMGetDMSNES(dm,&dmsnes);CHKERRQ(ierr); 1812d53ad75SBarry Smith ierr = DMSNESLoad(dmsnes,viewer);CHKERRQ(ierr); 1822d53ad75SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 18355849f57SBarry Smith ierr = KSPLoad(ksp,viewer);CHKERRQ(ierr); 18455849f57SBarry Smith PetscFunctionReturn(0); 18555849f57SBarry Smith } 1866a388c36SPeter Brune 1879804daf3SBarry Smith #include <petscdraw.h> 188e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 189e04113cfSBarry Smith #include <petscviewersaws.h> 190bfb97211SBarry Smith #endif 1914936397dSBarry Smith #undef __FUNCT__ 1924a2ae208SSatish Balay #define __FUNCT__ "SNESView" 1937e2c5f70SBarry Smith /*@C 1949b94acceSBarry Smith SNESView - Prints the SNES data structure. 1959b94acceSBarry Smith 1964c49b128SBarry Smith Collective on SNES 197fee21e36SBarry Smith 198c7afd0dbSLois Curfman McInnes Input Parameters: 199c7afd0dbSLois Curfman McInnes + SNES - the SNES context 200c7afd0dbSLois Curfman McInnes - viewer - visualization context 201c7afd0dbSLois Curfman McInnes 2029b94acceSBarry Smith Options Database Key: 203c8a8ba5cSLois Curfman McInnes . -snes_view - Calls SNESView() at end of SNESSolve() 2049b94acceSBarry Smith 2059b94acceSBarry Smith Notes: 2069b94acceSBarry Smith The available visualization contexts include 207b0a32e0cSBarry Smith + PETSC_VIEWER_STDOUT_SELF - standard output (default) 208b0a32e0cSBarry Smith - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 209c8a8ba5cSLois Curfman McInnes output where only the first processor opens 210c8a8ba5cSLois Curfman McInnes the file. All other processors send their 211c8a8ba5cSLois Curfman McInnes data to the first processor to print. 2129b94acceSBarry Smith 2133e081fefSLois Curfman McInnes The user can open an alternative visualization context with 214b0a32e0cSBarry Smith PetscViewerASCIIOpen() - output to a specified file. 2159b94acceSBarry Smith 21636851e7fSLois Curfman McInnes Level: beginner 21736851e7fSLois Curfman McInnes 2189b94acceSBarry Smith .keywords: SNES, view 2199b94acceSBarry Smith 220b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen() 2219b94acceSBarry Smith @*/ 2227087cfbeSBarry Smith PetscErrorCode SNESView(SNES snes,PetscViewer viewer) 2239b94acceSBarry Smith { 224fa9f3622SBarry Smith SNESKSPEW *kctx; 225dfbe8321SBarry Smith PetscErrorCode ierr; 22694b7f48cSBarry Smith KSP ksp; 2277f1410a3SPeter Brune SNESLineSearch linesearch; 22872a02f06SBarry Smith PetscBool iascii,isstring,isbinary,isdraw; 2292d53ad75SBarry Smith DMSNES dmsnes; 230e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 231536b137fSBarry Smith PetscBool issaws; 232bfb97211SBarry Smith #endif 2339b94acceSBarry Smith 2343a40ed3dSBarry Smith PetscFunctionBegin; 2350700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2363050cee2SBarry Smith if (!viewer) { 237ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&viewer);CHKERRQ(ierr); 2383050cee2SBarry Smith } 2390700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 240c9780b6fSBarry Smith PetscCheckSameComm(snes,1,viewer,2); 24174679c65SBarry Smith 242251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 243251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 24455849f57SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 24572a02f06SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 246e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 247536b137fSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 248bfb97211SBarry Smith #endif 24932077d6dSBarry Smith if (iascii) { 250dc0571f2SMatthew G. Knepley SNESNormSchedule normschedule; 251dc0571f2SMatthew G. Knepley 252dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer);CHKERRQ(ierr); 253fce1e034SJed Brown if (!snes->setupcalled) { 254fce1e034SJed Brown ierr = PetscViewerASCIIPrintf(viewer," SNES has not been set up so information may be incomplete\n");CHKERRQ(ierr); 255fce1e034SJed Brown } 256e7788613SBarry Smith if (snes->ops->view) { 257b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 258e7788613SBarry Smith ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 259b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2600ef38995SBarry Smith } 26177431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr); 26257622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%g, absolute=%g, solution=%g\n",(double)snes->rtol,(double)snes->abstol,(double)snes->stol);CHKERRQ(ierr); 26377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr); 26477431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr); 265dc0571f2SMatthew G. Knepley ierr = SNESGetNormSchedule(snes, &normschedule);CHKERRQ(ierr); 266dc0571f2SMatthew G. Knepley if (normschedule > 0) {ierr = PetscViewerASCIIPrintf(viewer," norm schedule %s\n",SNESNormSchedules[normschedule]);CHKERRQ(ierr);} 26717fe4bdfSPeter Brune if (snes->gridsequence) { 26817fe4bdfSPeter Brune ierr = PetscViewerASCIIPrintf(viewer," total number of grid sequence refinements=%D\n",snes->gridsequence);CHKERRQ(ierr); 26917fe4bdfSPeter Brune } 2709b94acceSBarry Smith if (snes->ksp_ewconv) { 271fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 2729b94acceSBarry Smith if (kctx) { 27377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr); 27457622a8eSBarry 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); 27557622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," gamma=%g, alpha=%g, alpha2=%g\n",(double)kctx->gamma,(double)kctx->alpha,(double)kctx->alpha2);CHKERRQ(ierr); 2769b94acceSBarry Smith } 2779b94acceSBarry Smith } 278eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 279eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n");CHKERRQ(ierr); 280eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 281eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr); 282eb1f6c34SBarry Smith } 283eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 284eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n");CHKERRQ(ierr); 285eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 28642f4f86dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr); 287eb1f6c34SBarry Smith } 2880f5bd95cSBarry Smith } else if (isstring) { 289317d6ea6SBarry Smith const char *type; 290454a90a3SBarry Smith ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 291b0a32e0cSBarry Smith ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr); 29255849f57SBarry Smith } else if (isbinary) { 29355849f57SBarry Smith PetscInt classid = SNES_FILE_CLASSID; 29455849f57SBarry Smith MPI_Comm comm; 29555849f57SBarry Smith PetscMPIInt rank; 29655849f57SBarry Smith char type[256]; 29755849f57SBarry Smith 29855849f57SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 29955849f57SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 30055849f57SBarry Smith if (!rank) { 30155849f57SBarry Smith ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 30289d949e2SBarry Smith ierr = PetscStrncpy(type,((PetscObject)snes)->type_name,sizeof(type));CHKERRQ(ierr); 30389d949e2SBarry Smith ierr = PetscViewerBinaryWrite(viewer,type,sizeof(type),PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr); 30455849f57SBarry Smith } 30555849f57SBarry Smith if (snes->ops->view) { 30655849f57SBarry Smith ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 30755849f57SBarry Smith } 30872a02f06SBarry Smith } else if (isdraw) { 30972a02f06SBarry Smith PetscDraw draw; 31072a02f06SBarry Smith char str[36]; 31189fd9fafSBarry Smith PetscReal x,y,bottom,h; 31272a02f06SBarry Smith 31372a02f06SBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 31472a02f06SBarry Smith ierr = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr); 31572a02f06SBarry Smith ierr = PetscStrcpy(str,"SNES: ");CHKERRQ(ierr); 31672a02f06SBarry Smith ierr = PetscStrcat(str,((PetscObject)snes)->type_name);CHKERRQ(ierr); 31751fa3d41SBarry Smith ierr = PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLUE,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr); 31889fd9fafSBarry Smith bottom = y - h; 31972a02f06SBarry Smith ierr = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr); 320c4646bacSPeter Brune if (snes->ops->view) { 321c4646bacSPeter Brune ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 322c4646bacSPeter Brune } 323e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 324536b137fSBarry Smith } else if (issaws) { 325d45a07a7SBarry Smith PetscMPIInt rank; 3262657e9d9SBarry Smith const char *name; 327d45a07a7SBarry Smith 3282657e9d9SBarry Smith ierr = PetscObjectGetName((PetscObject)snes,&name);CHKERRQ(ierr); 329d45a07a7SBarry Smith ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 330d45a07a7SBarry Smith if (!((PetscObject)snes)->amsmem && !rank) { 331d45a07a7SBarry Smith char dir[1024]; 332d45a07a7SBarry Smith 333e04113cfSBarry Smith ierr = PetscObjectViewSAWs((PetscObject)snes,viewer);CHKERRQ(ierr); 3342657e9d9SBarry Smith ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/its",name);CHKERRQ(ierr); 3352657e9d9SBarry Smith PetscStackCallSAWs(SAWs_Register,(dir,&snes->iter,1,SAWs_READ,SAWs_INT)); 336bfb97211SBarry Smith if (!snes->conv_hist) { 337a0931e03SBarry Smith ierr = SNESSetConvergenceHistory(snes,NULL,NULL,PETSC_DECIDE,PETSC_TRUE);CHKERRQ(ierr); 338bfb97211SBarry Smith } 3392657e9d9SBarry Smith ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/conv_hist",name);CHKERRQ(ierr); 3402657e9d9SBarry Smith PetscStackCallSAWs(SAWs_Register,(dir,snes->conv_hist,10,SAWs_READ,SAWs_DOUBLE)); 341f05ece33SBarry Smith } 342bfb97211SBarry Smith #endif 34372a02f06SBarry Smith } 34472a02f06SBarry Smith if (snes->linesearch) { 34572a02f06SBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 3467601faf0SJed Brown ierr = SNESGetLineSearch(snes, &linesearch);CHKERRQ(ierr); 34772a02f06SBarry Smith ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr); 34872a02f06SBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 34919bcc07fSBarry Smith } 35042f4f86dSBarry Smith if (snes->pc && snes->usespc) { 3514a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 3524a0c5b0cSMatthew G Knepley ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr); 3534a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 3544a0c5b0cSMatthew G Knepley } 3552d53ad75SBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 3562d53ad75SBarry Smith ierr = DMGetDMSNES(snes->dm,&dmsnes);CHKERRQ(ierr); 3572d53ad75SBarry Smith ierr = DMSNESView(dmsnes, viewer);CHKERRQ(ierr); 3582d53ad75SBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 3592c155ee1SBarry Smith if (snes->usesksp) { 3602c155ee1SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 361b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 36294b7f48cSBarry Smith ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 363b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 3642c155ee1SBarry Smith } 36572a02f06SBarry Smith if (isdraw) { 36672a02f06SBarry Smith PetscDraw draw; 36772a02f06SBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 36872a02f06SBarry Smith ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr); 3697f1410a3SPeter Brune } 3703a40ed3dSBarry Smith PetscFunctionReturn(0); 3719b94acceSBarry Smith } 3729b94acceSBarry Smith 37376b2cf59SMatthew Knepley /* 37476b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 37576b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 37676b2cf59SMatthew Knepley */ 37776b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 378a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 3796849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 38076b2cf59SMatthew Knepley 381e74ef692SMatthew Knepley #undef __FUNCT__ 382e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker" 383ac226902SBarry Smith /*@C 38476b2cf59SMatthew Knepley SNESAddOptionsChecker - Adds an additional function to check for SNES options. 38576b2cf59SMatthew Knepley 38676b2cf59SMatthew Knepley Not Collective 38776b2cf59SMatthew Knepley 38876b2cf59SMatthew Knepley Input Parameter: 38976b2cf59SMatthew Knepley . snescheck - function that checks for options 39076b2cf59SMatthew Knepley 39176b2cf59SMatthew Knepley Level: developer 39276b2cf59SMatthew Knepley 39376b2cf59SMatthew Knepley .seealso: SNESSetFromOptions() 39476b2cf59SMatthew Knepley @*/ 3957087cfbeSBarry Smith PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 39676b2cf59SMatthew Knepley { 39776b2cf59SMatthew Knepley PetscFunctionBegin; 398f23aa3ddSBarry Smith if (numberofsetfromoptions >= MAXSETFROMOPTIONS) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 39976b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 40076b2cf59SMatthew Knepley PetscFunctionReturn(0); 40176b2cf59SMatthew Knepley } 40276b2cf59SMatthew Knepley 4037087cfbeSBarry Smith extern PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 404aa3661deSLisandro Dalcin 405aa3661deSLisandro Dalcin #undef __FUNCT__ 406aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private" 407ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 408aa3661deSLisandro Dalcin { 409aa3661deSLisandro Dalcin Mat J; 410aa3661deSLisandro Dalcin KSP ksp; 411aa3661deSLisandro Dalcin PC pc; 412ace3abfcSBarry Smith PetscBool match; 413aa3661deSLisandro Dalcin PetscErrorCode ierr; 414895c21f2SBarry Smith MatNullSpace nullsp; 415aa3661deSLisandro Dalcin 416aa3661deSLisandro Dalcin PetscFunctionBegin; 4170700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 418aa3661deSLisandro Dalcin 41998613b67SLisandro Dalcin if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 42098613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 4212a7a6963SBarry Smith ierr = MatCreateVecs(A ? A : B, NULL,&snes->vec_func);CHKERRQ(ierr); 42298613b67SLisandro Dalcin } 42398613b67SLisandro Dalcin 424aa3661deSLisandro Dalcin if (version == 1) { 425aa3661deSLisandro Dalcin ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 42698613b67SLisandro Dalcin ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4279c6ac3b3SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 428aa3661deSLisandro Dalcin } else if (version == 2) { 429e32f2f54SBarry Smith if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 43082a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 431aa3661deSLisandro Dalcin ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr); 432aa3661deSLisandro Dalcin #else 433e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)"); 434aa3661deSLisandro Dalcin #endif 435a8248277SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2"); 436aa3661deSLisandro Dalcin 437895c21f2SBarry Smith /* attach any user provided null space that was on Amat to the newly created matrix free matrix */ 438895c21f2SBarry Smith if (snes->jacobian) { 439895c21f2SBarry Smith ierr = MatGetNullSpace(snes->jacobian,&nullsp);CHKERRQ(ierr); 440895c21f2SBarry Smith if (nullsp) { 441895c21f2SBarry Smith ierr = MatSetNullSpace(J,nullsp);CHKERRQ(ierr); 442895c21f2SBarry Smith } 443895c21f2SBarry Smith } 444895c21f2SBarry Smith 445aa3661deSLisandro Dalcin ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr); 446d3462f78SMatthew Knepley if (hasOperator) { 4473232da50SPeter Brune 448aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 449aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 450aa3661deSLisandro Dalcin ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 451aa3661deSLisandro Dalcin } else { 452aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 4533232da50SPeter Brune provided preconditioner Jacobian with the default matrix free version. */ 454172a4300SPeter Brune if ((snes->pcside == PC_LEFT) && snes->pc) { 455d728fb7dSPeter Brune if (!snes->jacobian){ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);} 456172a4300SPeter Brune } else { 45728a52e04SBarry Smith ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,0);CHKERRQ(ierr); 458172a4300SPeter Brune } 459aa3661deSLisandro Dalcin /* Force no preconditioner */ 460aa3661deSLisandro Dalcin ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 461aa3661deSLisandro Dalcin ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 462251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr); 463aa3661deSLisandro Dalcin if (!match) { 464aa3661deSLisandro Dalcin ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 465aa3661deSLisandro Dalcin ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 466aa3661deSLisandro Dalcin } 467aa3661deSLisandro Dalcin } 4686bf464f9SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 469aa3661deSLisandro Dalcin PetscFunctionReturn(0); 470aa3661deSLisandro Dalcin } 471aa3661deSLisandro Dalcin 4724a2ae208SSatish Balay #undef __FUNCT__ 473dfe15315SJed Brown #define __FUNCT__ "DMRestrictHook_SNESVecSol" 474dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx) 475dfe15315SJed Brown { 476dfe15315SJed Brown SNES snes = (SNES)ctx; 477dfe15315SJed Brown PetscErrorCode ierr; 4780298fd71SBarry Smith Vec Xfine,Xfine_named = NULL,Xcoarse; 479dfe15315SJed Brown 480dfe15315SJed Brown PetscFunctionBegin; 48116ebb321SJed Brown if (PetscLogPrintInfo) { 48216ebb321SJed Brown PetscInt finelevel,coarselevel,fineclevel,coarseclevel; 48316ebb321SJed Brown ierr = DMGetRefineLevel(dmfine,&finelevel);CHKERRQ(ierr); 48416ebb321SJed Brown ierr = DMGetCoarsenLevel(dmfine,&fineclevel);CHKERRQ(ierr); 48516ebb321SJed Brown ierr = DMGetRefineLevel(dmcoarse,&coarselevel);CHKERRQ(ierr); 48616ebb321SJed Brown ierr = DMGetCoarsenLevel(dmcoarse,&coarseclevel);CHKERRQ(ierr); 48716ebb321SJed Brown ierr = PetscInfo4(dmfine,"Restricting SNES solution vector from level %D-%D to level %D-%D\n",finelevel,fineclevel,coarselevel,coarseclevel);CHKERRQ(ierr); 48816ebb321SJed Brown } 489dfe15315SJed Brown if (dmfine == snes->dm) Xfine = snes->vec_sol; 490dfe15315SJed Brown else { 491dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr); 492dfe15315SJed Brown Xfine = Xfine_named; 493dfe15315SJed Brown } 494dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 495907f5c5aSLawrence Mitchell if (Inject) { 496907f5c5aSLawrence Mitchell ierr = MatRestrict(Inject,Xfine,Xcoarse);CHKERRQ(ierr); 497907f5c5aSLawrence Mitchell } else { 498dfe15315SJed Brown ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr); 499dfe15315SJed Brown ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr); 500907f5c5aSLawrence Mitchell } 501dfe15315SJed Brown ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 502dfe15315SJed Brown if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);} 503dfe15315SJed Brown PetscFunctionReturn(0); 504dfe15315SJed Brown } 505dfe15315SJed Brown 506dfe15315SJed Brown #undef __FUNCT__ 50716ebb321SJed Brown #define __FUNCT__ "DMCoarsenHook_SNESVecSol" 50816ebb321SJed Brown static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx) 50916ebb321SJed Brown { 51016ebb321SJed Brown PetscErrorCode ierr; 51116ebb321SJed Brown 51216ebb321SJed Brown PetscFunctionBegin; 51316ebb321SJed Brown ierr = DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx);CHKERRQ(ierr); 51416ebb321SJed Brown PetscFunctionReturn(0); 51516ebb321SJed Brown } 51616ebb321SJed Brown 51716ebb321SJed Brown #undef __FUNCT__ 518caa4e7f2SJed Brown #define __FUNCT__ "KSPComputeOperators_SNES" 519a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can 520a6950cb2SJed Brown * safely call SNESGetDM() in their residual evaluation routine. */ 52123ee1639SBarry Smith static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,void *ctx) 522caa4e7f2SJed Brown { 523caa4e7f2SJed Brown SNES snes = (SNES)ctx; 524caa4e7f2SJed Brown PetscErrorCode ierr; 525caa4e7f2SJed Brown Mat Asave = A,Bsave = B; 5260298fd71SBarry Smith Vec X,Xnamed = NULL; 527dfe15315SJed Brown DM dmsave; 5284e269d77SPeter Brune void *ctxsave; 529d1e9a80fSBarry Smith PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*); 530caa4e7f2SJed Brown 531caa4e7f2SJed Brown PetscFunctionBegin; 532dfe15315SJed Brown dmsave = snes->dm; 533dfe15315SJed Brown ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr); 534dfe15315SJed Brown if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */ 535dfe15315SJed Brown else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ 536dfe15315SJed Brown ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 537dfe15315SJed Brown X = Xnamed; 5380298fd71SBarry Smith ierr = SNESGetJacobian(snes,NULL,NULL,&jac,&ctxsave);CHKERRQ(ierr); 5394e269d77SPeter Brune /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */ 5408d359177SBarry Smith if (jac == SNESComputeJacobianDefaultColor) { 5418d359177SBarry Smith ierr = SNESSetJacobian(snes,NULL,NULL,SNESComputeJacobianDefaultColor,0);CHKERRQ(ierr); 542dfe15315SJed Brown } 5434e269d77SPeter Brune } 5444e269d77SPeter Brune /* put the previous context back */ 5454e269d77SPeter Brune 546d1e9a80fSBarry Smith ierr = SNESComputeJacobian(snes,X,A,B);CHKERRQ(ierr); 5478d359177SBarry Smith if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) { 5480298fd71SBarry Smith ierr = SNESSetJacobian(snes,NULL,NULL,jac,ctxsave);CHKERRQ(ierr); 5494e269d77SPeter Brune } 5504e269d77SPeter Brune 551ce94432eSBarry Smith if (A != Asave || B != Bsave) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"No support for changing matrices at this time"); 552dfe15315SJed Brown if (Xnamed) { 553dfe15315SJed Brown ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 554dfe15315SJed Brown } 555dfe15315SJed Brown snes->dm = dmsave; 556caa4e7f2SJed Brown PetscFunctionReturn(0); 557caa4e7f2SJed Brown } 558caa4e7f2SJed Brown 559caa4e7f2SJed Brown #undef __FUNCT__ 5606cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices" 5616cab3a1bSJed Brown /*@ 5626cab3a1bSJed Brown SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX() 5636cab3a1bSJed Brown 5646cab3a1bSJed Brown Collective 5656cab3a1bSJed Brown 5666cab3a1bSJed Brown Input Arguments: 5676cab3a1bSJed Brown . snes - snes to configure 5686cab3a1bSJed Brown 5696cab3a1bSJed Brown Level: developer 5706cab3a1bSJed Brown 5716cab3a1bSJed Brown .seealso: SNESSetUp() 5726cab3a1bSJed Brown @*/ 5736cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes) 5746cab3a1bSJed Brown { 5756cab3a1bSJed Brown PetscErrorCode ierr; 5766cab3a1bSJed Brown DM dm; 577942e3340SBarry Smith DMSNES sdm; 5786cab3a1bSJed Brown 5796cab3a1bSJed Brown PetscFunctionBegin; 5806cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 581942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 582ce94432eSBarry Smith if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_PLIB,"DMSNES not properly configured"); 583f5af7f23SKarl Rupp else if (!snes->jacobian && snes->mf) { 5846cab3a1bSJed Brown Mat J; 5856cab3a1bSJed Brown void *functx; 5866cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 5876cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 5886cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 5890298fd71SBarry Smith ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr); 5903232da50SPeter Brune ierr = SNESSetJacobian(snes,J,J,0,0);CHKERRQ(ierr); 5916cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 592caa4e7f2SJed Brown } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 5936cab3a1bSJed Brown Mat J,B; 5946cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 5956cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 5966cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 597b412c318SBarry Smith ierr = DMCreateMatrix(snes->dm,&B);CHKERRQ(ierr); 59806f20277SJed Brown /* sdm->computejacobian was already set to reach here */ 5990298fd71SBarry Smith ierr = SNESSetJacobian(snes,J,B,NULL,NULL);CHKERRQ(ierr); 6006cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 6016cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 602caa4e7f2SJed Brown } else if (!snes->jacobian_pre) { 6036cab3a1bSJed Brown Mat J,B; 6046cab3a1bSJed Brown J = snes->jacobian; 605b412c318SBarry Smith ierr = DMCreateMatrix(snes->dm,&B);CHKERRQ(ierr); 6060298fd71SBarry Smith ierr = SNESSetJacobian(snes,J ? J : B,B,NULL,NULL);CHKERRQ(ierr); 6076cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 6086cab3a1bSJed Brown } 609caa4e7f2SJed Brown { 610caa4e7f2SJed Brown KSP ksp; 611caa4e7f2SJed Brown ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 612caa4e7f2SJed Brown ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr); 61316ebb321SJed Brown ierr = DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 614caa4e7f2SJed Brown } 6156cab3a1bSJed Brown PetscFunctionReturn(0); 6166cab3a1bSJed Brown } 6176cab3a1bSJed Brown 6186cab3a1bSJed Brown #undef __FUNCT__ 6194a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions" 6209b94acceSBarry Smith /*@ 62194b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 6229b94acceSBarry Smith 623c7afd0dbSLois Curfman McInnes Collective on SNES 624c7afd0dbSLois Curfman McInnes 6259b94acceSBarry Smith Input Parameter: 6269b94acceSBarry Smith . snes - the SNES context 6279b94acceSBarry Smith 62836851e7fSLois Curfman McInnes Options Database Keys: 629722329fbSBarry Smith + -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, SNESType for complete list 63082738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 63182738288SBarry Smith of the change in the solution between steps 63270441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 633b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 634b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 635b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 6364839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 637ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 638a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 639e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 640b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 6412492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 64282738288SBarry Smith solver; hence iterations will continue until max_it 6431fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 64482738288SBarry Smith of convergence test 645e8105e01SRichard Katz . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 646e8105e01SRichard Katz filename given prints to stdout 647a6570f20SBarry Smith . -snes_monitor_solution - plots solution at each iteration 648a6570f20SBarry Smith . -snes_monitor_residual - plots residual (not its norm) at each iteration 649a6570f20SBarry Smith . -snes_monitor_solution_update - plots update to solution at each iteration 6504619e776SBarry Smith . -snes_monitor_lg_residualnorm - plots residual norm at each iteration 651459f5d12SBarry Smith . -snes_monitor_lg_range - plots residual norm at each iteration 652e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 653e2e60de9SPeter Brune . -snes_fd_color - use finite differences with coloring to compute Jacobian 6545968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 655fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 65682738288SBarry Smith 65782738288SBarry Smith Options Database for Eisenstat-Walker method: 658fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 6594b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 66036851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 66136851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 66236851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 66336851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 66436851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 66536851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 66682738288SBarry Smith 66711ca99fdSLois Curfman McInnes Notes: 66811ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 669a7f22e61SSatish Balay Users-Manual: ch_snes 67083e2fdc7SBarry Smith 67136851e7fSLois Curfman McInnes Level: beginner 67236851e7fSLois Curfman McInnes 6739b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 6749b94acceSBarry Smith 67569ed319cSSatish Balay .seealso: SNESSetOptionsPrefix() 6769b94acceSBarry Smith @*/ 6777087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 6789b94acceSBarry Smith { 6798afaa268SBarry Smith PetscBool flg,pcset,persist,set; 680d8f46077SPeter Brune PetscInt i,indx,lag,grids; 68104d7464bSBarry Smith const char *deft = SNESNEWTONLS; 68285385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 68385385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 684e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 685649052a6SBarry Smith PetscViewer monviewer; 68685385478SLisandro Dalcin PetscErrorCode ierr; 687c40d0f55SPeter Brune PCSide pcside; 688a64e098fSPeter Brune const char *optionsprefix; 6899b94acceSBarry Smith 6903a40ed3dSBarry Smith PetscFunctionBegin; 6910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 6920f51fdf8SToby Isaac ierr = SNESRegisterAll();CHKERRQ(ierr); 6933194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 694639ff905SBarry Smith if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name; 695a264d7a6SBarry Smith ierr = PetscOptionsFList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 696d64ed03dSBarry Smith if (flg) { 697186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 6987adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 699186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 700d64ed03dSBarry Smith } 70194ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,NULL);CHKERRQ(ierr); 70294ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,NULL);CHKERRQ(ierr); 703186905e3SBarry Smith 70494ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,NULL);CHKERRQ(ierr); 7050298fd71SBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,NULL);CHKERRQ(ierr); 7060298fd71SBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,NULL);CHKERRQ(ierr); 7070298fd71SBarry Smith ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,NULL);CHKERRQ(ierr); 7080298fd71SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,NULL);CHKERRQ(ierr); 7090298fd71SBarry Smith ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,NULL);CHKERRQ(ierr); 71085385478SLisandro Dalcin 711a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 712a8054027SBarry Smith if (flg) { 713a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 714a8054027SBarry Smith } 71537ec4e1aSPeter Brune ierr = PetscOptionsBool("-snes_lag_preconditioner_persists","Preconditioner lagging through multiple solves","SNESSetLagPreconditionerPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr); 71637ec4e1aSPeter Brune if (flg) { 71737ec4e1aSPeter Brune ierr = SNESSetLagPreconditionerPersists(snes,persist);CHKERRQ(ierr); 71837ec4e1aSPeter Brune } 719e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 720e35cf81dSBarry Smith if (flg) { 721e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 722e35cf81dSBarry Smith } 72337ec4e1aSPeter Brune ierr = PetscOptionsBool("-snes_lag_jacobian_persists","Jacobian lagging through multiple solves","SNESSetLagJacobianPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr); 72437ec4e1aSPeter Brune if (flg) { 72537ec4e1aSPeter Brune ierr = SNESSetLagJacobianPersists(snes,persist);CHKERRQ(ierr); 72637ec4e1aSPeter Brune } 72737ec4e1aSPeter Brune 728efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 729efd51863SBarry Smith if (flg) { 730efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 731efd51863SBarry Smith } 732a8054027SBarry Smith 73385385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 73485385478SLisandro Dalcin if (flg) { 73585385478SLisandro Dalcin switch (indx) { 7368d359177SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESConvergedDefault,NULL,NULL);CHKERRQ(ierr); break; 737e2a6519dSDmitry Karpeev case 1: ierr = SNESSetConvergenceTest(snes,SNESConvergedSkip,NULL,NULL);CHKERRQ(ierr); break; 73885385478SLisandro Dalcin } 73985385478SLisandro Dalcin } 74085385478SLisandro Dalcin 741365a6726SPeter Brune ierr = PetscOptionsEList("-snes_norm_schedule","SNES Norm schedule","SNESSetNormSchedule",SNESNormSchedules,5,"function",&indx,&flg);CHKERRQ(ierr); 742365a6726SPeter Brune if (flg) { ierr = SNESSetNormSchedule(snes,(SNESNormSchedule)indx);CHKERRQ(ierr); } 743fdacfa88SPeter Brune 74447073ea2SPeter Brune ierr = PetscOptionsEList("-snes_function_type","SNES Norm schedule","SNESSetFunctionType",SNESFunctionTypes,2,"unpreconditioned",&indx,&flg);CHKERRQ(ierr); 74547073ea2SPeter Brune if (flg) { ierr = SNESSetFunctionType(snes,(SNESFunctionType)indx);CHKERRQ(ierr); } 746186905e3SBarry Smith 74785385478SLisandro Dalcin kctx = (SNESKSPEW*)snes->kspconvctx; 74885385478SLisandro Dalcin 7490298fd71SBarry Smith ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,NULL);CHKERRQ(ierr); 750186905e3SBarry Smith 75194ae4db5SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,NULL);CHKERRQ(ierr); 75294ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,NULL);CHKERRQ(ierr); 75394ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,NULL);CHKERRQ(ierr); 75494ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,NULL);CHKERRQ(ierr); 75594ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,NULL);CHKERRQ(ierr); 75694ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,NULL);CHKERRQ(ierr); 75794ae4db5SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,NULL);CHKERRQ(ierr); 758186905e3SBarry Smith 75990d69ab7SBarry Smith flg = PETSC_FALSE; 7608afaa268SBarry Smith ierr = PetscOptionsBool("-snes_check_jacobian","Check each Jacobian with a differenced one","SNESUpdateCheckJacobian",flg,&flg,&set);CHKERRQ(ierr); 7618afaa268SBarry Smith if (set && flg) { 7625341784dSBarry Smith ierr = SNESSetUpdate(snes,SNESUpdateCheckJacobian);CHKERRQ(ierr); 7635341784dSBarry Smith } 7645341784dSBarry Smith 7655341784dSBarry Smith flg = PETSC_FALSE; 7668afaa268SBarry Smith ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,&set);CHKERRQ(ierr); 7678afaa268SBarry Smith if (set && flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 768eabae89aSBarry Smith 769a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 770e8105e01SRichard Katz if (flg) { 771ce94432eSBarry Smith ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)snes),monfilename,&monviewer);CHKERRQ(ierr); 772649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 773e8105e01SRichard Katz } 774eabae89aSBarry Smith 775b271bb04SBarry Smith ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 776b271bb04SBarry Smith if (flg) { 777b271bb04SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 778b271bb04SBarry Smith } 779b271bb04SBarry Smith 780a6570f20SBarry Smith ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 781eabae89aSBarry Smith if (flg) { 782ce94432eSBarry Smith ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)snes),monfilename,&monviewer);CHKERRQ(ierr); 783f1bef1bcSMatthew Knepley ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 784e8105e01SRichard Katz } 785eabae89aSBarry Smith 786a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 787eabae89aSBarry Smith if (flg) { 788ce94432eSBarry Smith ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)snes),monfilename,&monviewer);CHKERRQ(ierr); 789649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 790eabae89aSBarry Smith } 791eabae89aSBarry Smith 7922db13446SMatthew G. Knepley ierr = PetscOptionsString("-snes_monitor_field","Monitor norm of function (split into fields)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 7932db13446SMatthew G. Knepley if (flg) { 7942db13446SMatthew G. Knepley ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)snes),monfilename,&monviewer);CHKERRQ(ierr); 7952db13446SMatthew G. Knepley ierr = SNESMonitorSet(snes,SNESMonitorDefaultField,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 7962db13446SMatthew G. Knepley } 7972db13446SMatthew G. Knepley 7985180491cSLisandro Dalcin ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 7995180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 8005180491cSLisandro Dalcin 80190d69ab7SBarry Smith flg = PETSC_FALSE; 8020298fd71SBarry Smith ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,NULL);CHKERRQ(ierr); 803a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 80490d69ab7SBarry Smith flg = PETSC_FALSE; 8050298fd71SBarry Smith ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,NULL);CHKERRQ(ierr); 806a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 80790d69ab7SBarry Smith flg = PETSC_FALSE; 8080298fd71SBarry Smith ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,NULL);CHKERRQ(ierr); 809a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 81090d69ab7SBarry Smith flg = PETSC_FALSE; 8110298fd71SBarry Smith ierr = PetscOptionsBool("-snes_monitor_lg_residualnorm","Plot function norm at each iteration","SNESMonitorLGResidualNorm",flg,&flg,NULL);CHKERRQ(ierr); 812459f5d12SBarry Smith if (flg) { 813d96771aaSLisandro Dalcin PetscDrawLG ctx; 814459f5d12SBarry Smith 815d96771aaSLisandro Dalcin ierr = SNESMonitorLGCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,300,300,&ctx);CHKERRQ(ierr); 816d96771aaSLisandro Dalcin ierr = SNESMonitorSet(snes,SNESMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);CHKERRQ(ierr); 817459f5d12SBarry Smith } 81890d69ab7SBarry Smith flg = PETSC_FALSE; 8190298fd71SBarry Smith ierr = PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,NULL);CHKERRQ(ierr); 820459f5d12SBarry Smith if (flg) { 821459f5d12SBarry Smith PetscViewer ctx; 822e24b481bSBarry Smith 823ce94432eSBarry Smith ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&ctx);CHKERRQ(ierr); 824459f5d12SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 825459f5d12SBarry Smith } 8262e7541e6SPeter Brune 8272e7541e6SPeter Brune flg = PETSC_FALSE; 8280298fd71SBarry Smith ierr = PetscOptionsBool("-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",flg,&flg,NULL);CHKERRQ(ierr); 8292e7541e6SPeter Brune if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorJacUpdateSpectrum,0,0);CHKERRQ(ierr);} 8302e7541e6SPeter Brune 831cc0c4584SMatthew G. Knepley 832cc0c4584SMatthew G. Knepley ierr = PetscOptionsString("-snes_monitor_fields","Monitor norm of function per field","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 833cc0c4584SMatthew G. Knepley if (flg) { 834cc0c4584SMatthew G. Knepley ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)snes),monfilename,&monviewer);CHKERRQ(ierr); 835cc0c4584SMatthew G. Knepley ierr = SNESMonitorSet(snes,SNESMonitorFields,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 836cc0c4584SMatthew G. Knepley } 837cc0c4584SMatthew G. Knepley 83890d69ab7SBarry Smith flg = PETSC_FALSE; 8398d359177SBarry Smith ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESComputeJacobianDefault",flg,&flg,NULL);CHKERRQ(ierr); 8404b27c08aSLois Curfman McInnes if (flg) { 8416cab3a1bSJed Brown void *functx; 8420298fd71SBarry Smith ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr); 8438d359177SBarry Smith ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefault,functx);CHKERRQ(ierr); 844ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 8459b94acceSBarry Smith } 846639f9d9dSBarry Smith 84744848bc4SPeter Brune flg = PETSC_FALSE; 8488d359177SBarry Smith ierr = PetscOptionsBool("-snes_fd_function","Use finite differences (slow) to compute function from user objective","SNESObjectiveComputeFunctionDefaultFD",flg,&flg,NULL);CHKERRQ(ierr); 84997584545SPeter Brune if (flg) { 8508d359177SBarry Smith ierr = SNESSetFunction(snes,NULL,SNESObjectiveComputeFunctionDefaultFD,NULL);CHKERRQ(ierr); 85197584545SPeter Brune } 85297584545SPeter Brune 85397584545SPeter Brune flg = PETSC_FALSE; 8548d359177SBarry Smith ierr = PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESComputeJacobianDefaultColor",flg,&flg,NULL);CHKERRQ(ierr); 85544848bc4SPeter Brune if (flg) { 856c52e227fSPeter Brune DM dm; 857c52e227fSPeter Brune DMSNES sdm; 858c52e227fSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 859aace71b7SPeter Brune ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 860aace71b7SPeter Brune sdm->jacobianctx = NULL; 8618d359177SBarry Smith ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefaultColor,0);CHKERRQ(ierr); 86244848bc4SPeter Brune ierr = PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr); 86344848bc4SPeter Brune } 86444848bc4SPeter Brune 865aa3661deSLisandro Dalcin flg = PETSC_FALSE; 866d8f46077SPeter Brune ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&snes->mf_operator,&flg);CHKERRQ(ierr); 867d8f46077SPeter Brune if (flg && snes->mf_operator) { 868a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 869d8f46077SPeter Brune snes->mf = PETSC_TRUE; 870a8248277SBarry Smith } 871aa3661deSLisandro Dalcin flg = PETSC_FALSE; 872d8f46077SPeter Brune ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&snes->mf,&flg);CHKERRQ(ierr); 873d8f46077SPeter Brune if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE; 874d8f46077SPeter Brune ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,0);CHKERRQ(ierr); 875d28543b3SPeter Brune 876c40d0f55SPeter Brune flg = PETSC_FALSE; 877be95d8f1SBarry Smith ierr = SNESGetNPCSide(snes,&pcside);CHKERRQ(ierr); 878be95d8f1SBarry Smith ierr = PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetNPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);CHKERRQ(ierr); 879be95d8f1SBarry Smith if (flg) {ierr = SNESSetNPCSide(snes,pcside);CHKERRQ(ierr);} 880c40d0f55SPeter Brune 881e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 8828a70d858SHong Zhang /* 8838a70d858SHong Zhang Publish convergence information using SAWs 8848a70d858SHong Zhang */ 8858a70d858SHong Zhang flg = PETSC_FALSE; 8868a70d858SHong Zhang ierr = PetscOptionsBool("-snes_monitor_saws","Publish SNES progress using SAWs","SNESMonitorSet",flg,&flg,NULL);CHKERRQ(ierr); 8878a70d858SHong Zhang if (flg) { 8888a70d858SHong Zhang void *ctx; 8898a70d858SHong Zhang ierr = SNESMonitorSAWsCreate(snes,&ctx);CHKERRQ(ierr); 8908a70d858SHong Zhang ierr = SNESMonitorSet(snes,SNESMonitorSAWs,ctx,SNESMonitorSAWsDestroy);CHKERRQ(ierr); 8918a70d858SHong Zhang } 8928a70d858SHong Zhang #endif 8938a70d858SHong Zhang #if defined(PETSC_HAVE_SAWS) 894b90c6cbeSBarry Smith { 895b90c6cbeSBarry Smith PetscBool set; 896b90c6cbeSBarry Smith flg = PETSC_FALSE; 8978a70d858SHong Zhang ierr = PetscOptionsBool("-snes_saws_block","Block for SAWs at end of SNESSolve","PetscObjectSAWsBlock",((PetscObject)snes)->amspublishblock,&flg,&set);CHKERRQ(ierr); 898b90c6cbeSBarry Smith if (set) { 899e04113cfSBarry Smith ierr = PetscObjectSAWsSetBlock((PetscObject)snes,flg);CHKERRQ(ierr); 900b90c6cbeSBarry Smith } 901b90c6cbeSBarry Smith } 902b90c6cbeSBarry Smith #endif 903b90c6cbeSBarry Smith 90476b2cf59SMatthew Knepley for (i = 0; i < numberofsetfromoptions; i++) { 90576b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 90676b2cf59SMatthew Knepley } 90776b2cf59SMatthew Knepley 908e7788613SBarry Smith if (snes->ops->setfromoptions) { 909e55864a3SBarry Smith ierr = (*snes->ops->setfromoptions)(PetscOptionsObject,snes);CHKERRQ(ierr); 910639f9d9dSBarry Smith } 9115d973c19SBarry Smith 9125d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 9135d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 914b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 9154bbc92c1SBarry Smith 9169e764e56SPeter Brune if (!snes->linesearch) { 9177601faf0SJed Brown ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 9189e764e56SPeter Brune } 919f1c6b773SPeter Brune ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr); 9209e764e56SPeter Brune 9216991f827SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 9226991f827SBarry Smith ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre);CHKERRQ(ierr); 9236991f827SBarry Smith ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 9246991f827SBarry Smith 925be95d8f1SBarry Smith /* if someone has set the SNES NPC type, create it. */ 92651e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 92751e86f29SPeter Brune ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 92851e86f29SPeter Brune if (pcset && (!snes->pc)) { 929be95d8f1SBarry Smith ierr = SNESGetNPC(snes, &snes->pc);CHKERRQ(ierr); 93051e86f29SPeter Brune } 9313a40ed3dSBarry Smith PetscFunctionReturn(0); 9329b94acceSBarry Smith } 9339b94acceSBarry Smith 934d25893d9SBarry Smith #undef __FUNCT__ 935d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 936bb9467b5SJed Brown /*@C 937d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 938d25893d9SBarry Smith the nonlinear solvers. 939d25893d9SBarry Smith 940d25893d9SBarry Smith Logically Collective on SNES 941d25893d9SBarry Smith 942d25893d9SBarry Smith Input Parameters: 943d25893d9SBarry Smith + snes - the SNES context 944d25893d9SBarry Smith . compute - function to compute the context 945d25893d9SBarry Smith - destroy - function to destroy the context 946d25893d9SBarry Smith 947d25893d9SBarry Smith Level: intermediate 948d25893d9SBarry Smith 949bb9467b5SJed Brown Notes: 950bb9467b5SJed Brown This function is currently not available from Fortran. 951bb9467b5SJed Brown 952d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 953d25893d9SBarry Smith 954d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 955d25893d9SBarry Smith @*/ 956d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 957d25893d9SBarry Smith { 958d25893d9SBarry Smith PetscFunctionBegin; 959d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 960d25893d9SBarry Smith snes->ops->usercompute = compute; 961d25893d9SBarry Smith snes->ops->userdestroy = destroy; 962d25893d9SBarry Smith PetscFunctionReturn(0); 963d25893d9SBarry Smith } 964a847f771SSatish Balay 9654a2ae208SSatish Balay #undef __FUNCT__ 9664a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 967b07ff414SBarry Smith /*@ 9689b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 9699b94acceSBarry Smith the nonlinear solvers. 9709b94acceSBarry Smith 9713f9fe445SBarry Smith Logically Collective on SNES 972fee21e36SBarry Smith 973c7afd0dbSLois Curfman McInnes Input Parameters: 974c7afd0dbSLois Curfman McInnes + snes - the SNES context 975c7afd0dbSLois Curfman McInnes - usrP - optional user context 976c7afd0dbSLois Curfman McInnes 97736851e7fSLois Curfman McInnes Level: intermediate 97836851e7fSLois Curfman McInnes 979daf670e6SBarry Smith Fortran Notes: To use this from Fortran you must write a Fortran interface definition for this 980daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 981daf670e6SBarry Smith 9829b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 9839b94acceSBarry Smith 984ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext() 9859b94acceSBarry Smith @*/ 9867087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 9879b94acceSBarry Smith { 9881b2093e4SBarry Smith PetscErrorCode ierr; 989b07ff414SBarry Smith KSP ksp; 9901b2093e4SBarry Smith 9913a40ed3dSBarry Smith PetscFunctionBegin; 9920700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 993b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 994b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 9959b94acceSBarry Smith snes->user = usrP; 9963a40ed3dSBarry Smith PetscFunctionReturn(0); 9979b94acceSBarry Smith } 99874679c65SBarry Smith 9994a2ae208SSatish Balay #undef __FUNCT__ 10004a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 1001b07ff414SBarry Smith /*@ 10029b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 10039b94acceSBarry Smith nonlinear solvers. 10049b94acceSBarry Smith 1005c7afd0dbSLois Curfman McInnes Not Collective 1006c7afd0dbSLois Curfman McInnes 10079b94acceSBarry Smith Input Parameter: 10089b94acceSBarry Smith . snes - SNES context 10099b94acceSBarry Smith 10109b94acceSBarry Smith Output Parameter: 10119b94acceSBarry Smith . usrP - user context 10129b94acceSBarry Smith 1013daf670e6SBarry Smith Fortran Notes: To use this from Fortran you must write a Fortran interface definition for this 1014daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1015daf670e6SBarry Smith 101636851e7fSLois Curfman McInnes Level: intermediate 101736851e7fSLois Curfman McInnes 10189b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 10199b94acceSBarry Smith 10209b94acceSBarry Smith .seealso: SNESSetApplicationContext() 10219b94acceSBarry Smith @*/ 1022e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 10239b94acceSBarry Smith { 10243a40ed3dSBarry Smith PetscFunctionBegin; 10250700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1026e71120c6SJed Brown *(void**)usrP = snes->user; 10273a40ed3dSBarry Smith PetscFunctionReturn(0); 10289b94acceSBarry Smith } 102974679c65SBarry Smith 10304a2ae208SSatish Balay #undef __FUNCT__ 10314a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 10329b94acceSBarry Smith /*@ 1033c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 1034c8228a4eSBarry Smith at this time. 10359b94acceSBarry Smith 1036c7afd0dbSLois Curfman McInnes Not Collective 1037c7afd0dbSLois Curfman McInnes 10389b94acceSBarry Smith Input Parameter: 10399b94acceSBarry Smith . snes - SNES context 10409b94acceSBarry Smith 10419b94acceSBarry Smith Output Parameter: 10429b94acceSBarry Smith . iter - iteration number 10439b94acceSBarry Smith 1044c8228a4eSBarry Smith Notes: 1045c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 1046c8228a4eSBarry Smith 1047c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 104808405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 104908405cd6SLois Curfman McInnes .vb 105008405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 105108405cd6SLois Curfman McInnes if (!(it % 2)) { 105208405cd6SLois Curfman McInnes [compute Jacobian here] 105308405cd6SLois Curfman McInnes } 105408405cd6SLois Curfman McInnes .ve 1055c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 105608405cd6SLois Curfman McInnes recomputed every second SNES iteration. 1057c8228a4eSBarry Smith 105836851e7fSLois Curfman McInnes Level: intermediate 105936851e7fSLois Curfman McInnes 10602b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 10612b668275SBarry Smith 106271dbe336SPeter Brune .seealso: SNESGetLinearSolveIterations() 10639b94acceSBarry Smith @*/ 10647087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt *iter) 10659b94acceSBarry Smith { 10663a40ed3dSBarry Smith PetscFunctionBegin; 10670700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10684482741eSBarry Smith PetscValidIntPointer(iter,2); 10699b94acceSBarry Smith *iter = snes->iter; 10703a40ed3dSBarry Smith PetscFunctionReturn(0); 10719b94acceSBarry Smith } 107274679c65SBarry Smith 10734a2ae208SSatish Balay #undef __FUNCT__ 1074360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber" 1075360c497dSPeter Brune /*@ 1076360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 1077360c497dSPeter Brune 1078360c497dSPeter Brune Not Collective 1079360c497dSPeter Brune 1080360c497dSPeter Brune Input Parameter: 1081360c497dSPeter Brune . snes - SNES context 1082360c497dSPeter Brune . iter - iteration number 1083360c497dSPeter Brune 1084360c497dSPeter Brune Level: developer 1085360c497dSPeter Brune 1086360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number, 1087360c497dSPeter Brune 108871dbe336SPeter Brune .seealso: SNESGetLinearSolveIterations() 1089360c497dSPeter Brune @*/ 1090360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 1091360c497dSPeter Brune { 1092360c497dSPeter Brune PetscErrorCode ierr; 1093360c497dSPeter Brune 1094360c497dSPeter Brune PetscFunctionBegin; 1095360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1096e04113cfSBarry Smith ierr = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr); 1097360c497dSPeter Brune snes->iter = iter; 1098e04113cfSBarry Smith ierr = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr); 1099360c497dSPeter Brune PetscFunctionReturn(0); 1100360c497dSPeter Brune } 1101360c497dSPeter Brune 1102360c497dSPeter Brune #undef __FUNCT__ 1103b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 11049b94acceSBarry Smith /*@ 1105b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 11069b94acceSBarry Smith attempted by the nonlinear solver. 11079b94acceSBarry Smith 1108c7afd0dbSLois Curfman McInnes Not Collective 1109c7afd0dbSLois Curfman McInnes 11109b94acceSBarry Smith Input Parameter: 11119b94acceSBarry Smith . snes - SNES context 11129b94acceSBarry Smith 11139b94acceSBarry Smith Output Parameter: 11149b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 11159b94acceSBarry Smith 1116c96a6f78SLois Curfman McInnes Notes: 1117c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1118c96a6f78SLois Curfman McInnes 111936851e7fSLois Curfman McInnes Level: intermediate 112036851e7fSLois Curfman McInnes 11219b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 112258ebbce7SBarry Smith 1123e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 112458ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 11259b94acceSBarry Smith @*/ 11267087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt *nfails) 11279b94acceSBarry Smith { 11283a40ed3dSBarry Smith PetscFunctionBegin; 11290700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11304482741eSBarry Smith PetscValidIntPointer(nfails,2); 113150ffb88aSMatthew Knepley *nfails = snes->numFailures; 113250ffb88aSMatthew Knepley PetscFunctionReturn(0); 113350ffb88aSMatthew Knepley } 113450ffb88aSMatthew Knepley 113550ffb88aSMatthew Knepley #undef __FUNCT__ 1136b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 113750ffb88aSMatthew Knepley /*@ 1138b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 113950ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 114050ffb88aSMatthew Knepley 114150ffb88aSMatthew Knepley Not Collective 114250ffb88aSMatthew Knepley 114350ffb88aSMatthew Knepley Input Parameters: 114450ffb88aSMatthew Knepley + snes - SNES context 114550ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 114650ffb88aSMatthew Knepley 114750ffb88aSMatthew Knepley Level: intermediate 114850ffb88aSMatthew Knepley 114950ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 115058ebbce7SBarry Smith 1151e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 115258ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 115350ffb88aSMatthew Knepley @*/ 11547087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 115550ffb88aSMatthew Knepley { 115650ffb88aSMatthew Knepley PetscFunctionBegin; 11570700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 115850ffb88aSMatthew Knepley snes->maxFailures = maxFails; 115950ffb88aSMatthew Knepley PetscFunctionReturn(0); 116050ffb88aSMatthew Knepley } 116150ffb88aSMatthew Knepley 116250ffb88aSMatthew Knepley #undef __FUNCT__ 1163b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 116450ffb88aSMatthew Knepley /*@ 1165b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 116650ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 116750ffb88aSMatthew Knepley 116850ffb88aSMatthew Knepley Not Collective 116950ffb88aSMatthew Knepley 117050ffb88aSMatthew Knepley Input Parameter: 117150ffb88aSMatthew Knepley . snes - SNES context 117250ffb88aSMatthew Knepley 117350ffb88aSMatthew Knepley Output Parameter: 117450ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 117550ffb88aSMatthew Knepley 117650ffb88aSMatthew Knepley Level: intermediate 117750ffb88aSMatthew Knepley 117850ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 117958ebbce7SBarry Smith 1180e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 118158ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 118258ebbce7SBarry Smith 118350ffb88aSMatthew Knepley @*/ 11847087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 118550ffb88aSMatthew Knepley { 118650ffb88aSMatthew Knepley PetscFunctionBegin; 11870700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11884482741eSBarry Smith PetscValidIntPointer(maxFails,2); 118950ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 11903a40ed3dSBarry Smith PetscFunctionReturn(0); 11919b94acceSBarry Smith } 1192a847f771SSatish Balay 11934a2ae208SSatish Balay #undef __FUNCT__ 11942541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 11952541af92SBarry Smith /*@ 11962541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 11972541af92SBarry Smith done by SNES. 11982541af92SBarry Smith 11992541af92SBarry Smith Not Collective 12002541af92SBarry Smith 12012541af92SBarry Smith Input Parameter: 12022541af92SBarry Smith . snes - SNES context 12032541af92SBarry Smith 12042541af92SBarry Smith Output Parameter: 12052541af92SBarry Smith . nfuncs - number of evaluations 12062541af92SBarry Smith 12072541af92SBarry Smith Level: intermediate 12082541af92SBarry Smith 1209971e163fSPeter Brune Notes: Reset every time SNESSolve is called unless SNESSetCountersReset() is used. 1210971e163fSPeter Brune 12112541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 121258ebbce7SBarry Smith 1213971e163fSPeter Brune .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), SNESSetCountersReset() 12142541af92SBarry Smith @*/ 12157087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 12162541af92SBarry Smith { 12172541af92SBarry Smith PetscFunctionBegin; 12180700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12192541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 12202541af92SBarry Smith *nfuncs = snes->nfuncs; 12212541af92SBarry Smith PetscFunctionReturn(0); 12222541af92SBarry Smith } 12232541af92SBarry Smith 12242541af92SBarry Smith #undef __FUNCT__ 12253d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 12263d4c4710SBarry Smith /*@ 12273d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 12283d4c4710SBarry Smith linear solvers. 12293d4c4710SBarry Smith 12303d4c4710SBarry Smith Not Collective 12313d4c4710SBarry Smith 12323d4c4710SBarry Smith Input Parameter: 12333d4c4710SBarry Smith . snes - SNES context 12343d4c4710SBarry Smith 12353d4c4710SBarry Smith Output Parameter: 12363d4c4710SBarry Smith . nfails - number of failed solves 12373d4c4710SBarry Smith 12389d85da0cSMatthew G. Knepley Level: intermediate 12399d85da0cSMatthew G. Knepley 12409d85da0cSMatthew G. Knepley Options Database Keys: 12419d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 12429d85da0cSMatthew G. Knepley 12433d4c4710SBarry Smith Notes: 12443d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 12453d4c4710SBarry Smith 12463d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 124758ebbce7SBarry Smith 1248e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 12493d4c4710SBarry Smith @*/ 12507087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt *nfails) 12513d4c4710SBarry Smith { 12523d4c4710SBarry Smith PetscFunctionBegin; 12530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12543d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 12553d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 12563d4c4710SBarry Smith PetscFunctionReturn(0); 12573d4c4710SBarry Smith } 12583d4c4710SBarry Smith 12593d4c4710SBarry Smith #undef __FUNCT__ 12603d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 12613d4c4710SBarry Smith /*@ 12623d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 12633d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 12643d4c4710SBarry Smith 12653f9fe445SBarry Smith Logically Collective on SNES 12663d4c4710SBarry Smith 12673d4c4710SBarry Smith Input Parameters: 12683d4c4710SBarry Smith + snes - SNES context 12693d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 12703d4c4710SBarry Smith 12713d4c4710SBarry Smith Level: intermediate 12723d4c4710SBarry Smith 12739d85da0cSMatthew G. Knepley Options Database Keys: 12749d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 12759d85da0cSMatthew G. Knepley 1276a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 12773d4c4710SBarry Smith 12783d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 12793d4c4710SBarry Smith 128058ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 12813d4c4710SBarry Smith @*/ 12827087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 12833d4c4710SBarry Smith { 12843d4c4710SBarry Smith PetscFunctionBegin; 12850700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1286c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 12873d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 12883d4c4710SBarry Smith PetscFunctionReturn(0); 12893d4c4710SBarry Smith } 12903d4c4710SBarry Smith 12913d4c4710SBarry Smith #undef __FUNCT__ 12923d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 12933d4c4710SBarry Smith /*@ 12943d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 12953d4c4710SBarry Smith are allowed before SNES terminates 12963d4c4710SBarry Smith 12973d4c4710SBarry Smith Not Collective 12983d4c4710SBarry Smith 12993d4c4710SBarry Smith Input Parameter: 13003d4c4710SBarry Smith . snes - SNES context 13013d4c4710SBarry Smith 13023d4c4710SBarry Smith Output Parameter: 13033d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 13043d4c4710SBarry Smith 13053d4c4710SBarry Smith Level: intermediate 13063d4c4710SBarry Smith 13073d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 13083d4c4710SBarry Smith 13093d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 13103d4c4710SBarry Smith 1311e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 13123d4c4710SBarry Smith @*/ 13137087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 13143d4c4710SBarry Smith { 13153d4c4710SBarry Smith PetscFunctionBegin; 13160700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13173d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 13183d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 13193d4c4710SBarry Smith PetscFunctionReturn(0); 13203d4c4710SBarry Smith } 13213d4c4710SBarry Smith 13223d4c4710SBarry Smith #undef __FUNCT__ 1323b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 1324c96a6f78SLois Curfman McInnes /*@ 1325b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1326c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1327c96a6f78SLois Curfman McInnes 1328c7afd0dbSLois Curfman McInnes Not Collective 1329c7afd0dbSLois Curfman McInnes 1330c96a6f78SLois Curfman McInnes Input Parameter: 1331c96a6f78SLois Curfman McInnes . snes - SNES context 1332c96a6f78SLois Curfman McInnes 1333c96a6f78SLois Curfman McInnes Output Parameter: 1334c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1335c96a6f78SLois Curfman McInnes 1336c96a6f78SLois Curfman McInnes Notes: 1337971e163fSPeter Brune This counter is reset to zero for each successive call to SNESSolve() unless SNESSetCountersReset() is used. 1338c96a6f78SLois Curfman McInnes 133936851e7fSLois Curfman McInnes Level: intermediate 134036851e7fSLois Curfman McInnes 1341c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 13422b668275SBarry Smith 134371dbe336SPeter Brune .seealso: SNESGetIterationNumber(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESSetCountersReset() 1344c96a6f78SLois Curfman McInnes @*/ 13457087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt *lits) 1346c96a6f78SLois Curfman McInnes { 13473a40ed3dSBarry Smith PetscFunctionBegin; 13480700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13494482741eSBarry Smith PetscValidIntPointer(lits,2); 1350c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 13513a40ed3dSBarry Smith PetscFunctionReturn(0); 1352c96a6f78SLois Curfman McInnes } 1353c96a6f78SLois Curfman McInnes 1354971e163fSPeter Brune #undef __FUNCT__ 1355971e163fSPeter Brune #define __FUNCT__ "SNESSetCountersReset" 1356971e163fSPeter Brune /*@ 1357971e163fSPeter Brune SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations 1358971e163fSPeter Brune are reset every time SNESSolve() is called. 1359971e163fSPeter Brune 1360971e163fSPeter Brune Logically Collective on SNES 1361971e163fSPeter Brune 1362971e163fSPeter Brune Input Parameter: 1363971e163fSPeter Brune + snes - SNES context 1364971e163fSPeter Brune - reset - whether to reset the counters or not 1365971e163fSPeter Brune 1366971e163fSPeter Brune Notes: 1367fa19ca70SBarry Smith This defaults to PETSC_TRUE 1368971e163fSPeter Brune 1369971e163fSPeter Brune Level: developer 1370971e163fSPeter Brune 1371971e163fSPeter Brune .keywords: SNES, nonlinear, set, reset, number, linear, iterations 1372971e163fSPeter Brune 1373734794cfSBarry Smith .seealso: SNESGetNumberFunctionEvals(), SNESGetLinearSolveIterations(), SNESGetNPC() 1374971e163fSPeter Brune @*/ 1375971e163fSPeter Brune PetscErrorCode SNESSetCountersReset(SNES snes,PetscBool reset) 1376971e163fSPeter Brune { 1377971e163fSPeter Brune PetscFunctionBegin; 1378971e163fSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1379971e163fSPeter Brune PetscValidLogicalCollectiveBool(snes,reset,2); 1380971e163fSPeter Brune snes->counters_reset = reset; 1381971e163fSPeter Brune PetscFunctionReturn(0); 1382971e163fSPeter Brune } 1383971e163fSPeter Brune 138482bf6240SBarry Smith 13854a2ae208SSatish Balay #undef __FUNCT__ 13862999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 13872999313aSBarry Smith /*@ 13882999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 13892999313aSBarry Smith 13902999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 13912999313aSBarry Smith 13922999313aSBarry Smith Input Parameters: 13932999313aSBarry Smith + snes - the SNES context 13942999313aSBarry Smith - ksp - the KSP context 13952999313aSBarry Smith 13962999313aSBarry Smith Notes: 13972999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 13982999313aSBarry Smith so this routine is rarely needed. 13992999313aSBarry Smith 14002999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 14012999313aSBarry Smith decreased by one. 14022999313aSBarry Smith 14032999313aSBarry Smith Level: developer 14042999313aSBarry Smith 14052999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 14062999313aSBarry Smith 14072999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 14082999313aSBarry Smith @*/ 14097087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 14102999313aSBarry Smith { 14112999313aSBarry Smith PetscErrorCode ierr; 14122999313aSBarry Smith 14132999313aSBarry Smith PetscFunctionBegin; 14140700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14150700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 14162999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 14177dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1418906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 14192999313aSBarry Smith snes->ksp = ksp; 14202999313aSBarry Smith PetscFunctionReturn(0); 14212999313aSBarry Smith } 14222999313aSBarry Smith 14239b94acceSBarry Smith /* -----------------------------------------------------------*/ 14244a2ae208SSatish Balay #undef __FUNCT__ 14254a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 142652baeb72SSatish Balay /*@ 14279b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 14289b94acceSBarry Smith 1429c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1430c7afd0dbSLois Curfman McInnes 1431c7afd0dbSLois Curfman McInnes Input Parameters: 1432906ed7ccSBarry Smith . comm - MPI communicator 14339b94acceSBarry Smith 14349b94acceSBarry Smith Output Parameter: 14359b94acceSBarry Smith . outsnes - the new SNES context 14369b94acceSBarry Smith 1437c7afd0dbSLois Curfman McInnes Options Database Keys: 1438c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1439c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1440c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1441c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1442c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1443c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1444c1f60f51SBarry Smith 144536851e7fSLois Curfman McInnes Level: beginner 144636851e7fSLois Curfman McInnes 14479b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 14489b94acceSBarry Smith 1449a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1450a8054027SBarry Smith 14519b94acceSBarry Smith @*/ 14527087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 14539b94acceSBarry Smith { 1454dfbe8321SBarry Smith PetscErrorCode ierr; 14559b94acceSBarry Smith SNES snes; 1456fa9f3622SBarry Smith SNESKSPEW *kctx; 145737fcc0dbSBarry Smith 14583a40ed3dSBarry Smith PetscFunctionBegin; 1459ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 14600298fd71SBarry Smith *outsnes = NULL; 1461607a6623SBarry Smith ierr = SNESInitializePackage();CHKERRQ(ierr); 14628ba1e511SMatthew Knepley 146373107ff1SLisandro Dalcin ierr = PetscHeaderCreate(snes,SNES_CLASSID,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 14647adad957SLisandro Dalcin 14658d359177SBarry Smith snes->ops->converged = SNESConvergedDefault; 14662c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 146788976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 14689b94acceSBarry Smith snes->max_its = 50; 14699750a799SBarry Smith snes->max_funcs = 10000; 14709b94acceSBarry Smith snes->norm = 0.0; 1471365a6726SPeter Brune snes->normschedule = SNES_NORM_ALWAYS; 14726c67d002SPeter Brune snes->functype = SNES_FUNCTION_DEFAULT; 14733a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 14743a2046daSBarry Smith snes->rtol = 1.e-5; 14753a2046daSBarry Smith #else 1476b4874afaSBarry Smith snes->rtol = 1.e-8; 14773a2046daSBarry Smith #endif 1478b4874afaSBarry Smith snes->ttol = 0.0; 14793a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 14803a2046daSBarry Smith snes->abstol = 1.e-25; 14813a2046daSBarry Smith #else 148270441072SBarry Smith snes->abstol = 1.e-50; 14833a2046daSBarry Smith #endif 1484c60f73f4SPeter Brune snes->stol = 1.e-8; 14853a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 14863a2046daSBarry Smith snes->deltatol = 1.e-6; 14873a2046daSBarry Smith #else 14884b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 14893a2046daSBarry Smith #endif 14909b94acceSBarry Smith snes->nfuncs = 0; 149150ffb88aSMatthew Knepley snes->numFailures = 0; 149250ffb88aSMatthew Knepley snes->maxFailures = 1; 14937a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1494e35cf81dSBarry Smith snes->lagjacobian = 1; 149537ec4e1aSPeter Brune snes->jac_iter = 0; 149637ec4e1aSPeter Brune snes->lagjac_persist = PETSC_FALSE; 1497a8054027SBarry Smith snes->lagpreconditioner = 1; 149837ec4e1aSPeter Brune snes->pre_iter = 0; 149937ec4e1aSPeter Brune snes->lagpre_persist = PETSC_FALSE; 1500639f9d9dSBarry Smith snes->numbermonitors = 0; 15019b94acceSBarry Smith snes->data = 0; 15024dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1503186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 15046f24a144SLois Curfman McInnes snes->nwork = 0; 150558c9b817SLisandro Dalcin snes->work = 0; 150658c9b817SLisandro Dalcin snes->nvwork = 0; 150758c9b817SLisandro Dalcin snes->vwork = 0; 1508758f92a0SBarry Smith snes->conv_hist_len = 0; 1509758f92a0SBarry Smith snes->conv_hist_max = 0; 15100298fd71SBarry Smith snes->conv_hist = NULL; 15110298fd71SBarry Smith snes->conv_hist_its = NULL; 1512758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1513971e163fSPeter Brune snes->counters_reset = PETSC_TRUE; 1514e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1515184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 1516c40d0f55SPeter Brune snes->pcside = PC_RIGHT; 1517c40d0f55SPeter Brune 1518d8f46077SPeter Brune snes->mf = PETSC_FALSE; 1519d8f46077SPeter Brune snes->mf_operator = PETSC_FALSE; 1520d8f46077SPeter Brune snes->mf_version = 1; 1521d8f46077SPeter Brune 15223d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 15233d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 15243d4c4710SBarry Smith 1525349187a7SBarry Smith snes->vizerotolerance = 1.e-8; 1526349187a7SBarry Smith 15279b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 1528b00a9115SJed Brown ierr = PetscNewLog(snes,&kctx);CHKERRQ(ierr); 1529f5af7f23SKarl Rupp 15309b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 15319b94acceSBarry Smith kctx->version = 2; 15329b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 15339b94acceSBarry Smith this was too large for some test cases */ 153475567043SBarry Smith kctx->rtol_last = 0.0; 15359b94acceSBarry Smith kctx->rtol_max = .9; 15369b94acceSBarry Smith kctx->gamma = 1.0; 153762d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 153871f87433Sdalcinl kctx->alpha2 = kctx->alpha; 15399b94acceSBarry Smith kctx->threshold = .1; 154075567043SBarry Smith kctx->lresid_last = 0.0; 154175567043SBarry Smith kctx->norm_last = 0.0; 15429b94acceSBarry Smith 15439b94acceSBarry Smith *outsnes = snes; 15443a40ed3dSBarry Smith PetscFunctionReturn(0); 15459b94acceSBarry Smith } 15469b94acceSBarry Smith 154788f0584fSBarry Smith /*MC 1548411c0326SBarry Smith SNESFunction - Functional form used to convey the nonlinear function to be solved by SNES 154988f0584fSBarry Smith 155088f0584fSBarry Smith Synopsis: 1551411c0326SBarry Smith #include "petscsnes.h" 1552411c0326SBarry Smith PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx); 155388f0584fSBarry Smith 155488f0584fSBarry Smith Input Parameters: 155588f0584fSBarry Smith + snes - the SNES context 155688f0584fSBarry Smith . x - state at which to evaluate residual 155788f0584fSBarry Smith - ctx - optional user-defined function context, passed in with SNESSetFunction() 155888f0584fSBarry Smith 155988f0584fSBarry Smith Output Parameter: 156088f0584fSBarry Smith . f - vector to put residual (function value) 156188f0584fSBarry Smith 1562878cb397SSatish Balay Level: intermediate 1563878cb397SSatish Balay 156488f0584fSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 156588f0584fSBarry Smith M*/ 156688f0584fSBarry Smith 15674a2ae208SSatish Balay #undef __FUNCT__ 15684a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 15699b94acceSBarry Smith /*@C 15709b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 15719b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 15729b94acceSBarry Smith equations. 15739b94acceSBarry Smith 15743f9fe445SBarry Smith Logically Collective on SNES 1575fee21e36SBarry Smith 1576c7afd0dbSLois Curfman McInnes Input Parameters: 1577c7afd0dbSLois Curfman McInnes + snes - the SNES context 1578c7afd0dbSLois Curfman McInnes . r - vector to store function value 1579f8b49ee9SBarry Smith . f - function evaluation routine; see SNESFunction for calling sequence details 1580c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 15810298fd71SBarry Smith function evaluation routine (may be NULL) 15829b94acceSBarry Smith 15839b94acceSBarry Smith Notes: 15849b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 15859b94acceSBarry Smith $ f'(x) x = -f(x), 1586c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 15879b94acceSBarry Smith 158836851e7fSLois Curfman McInnes Level: beginner 158936851e7fSLois Curfman McInnes 15909b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 15919b94acceSBarry Smith 1592bf388a1fSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard(), SNESFunction 15939b94acceSBarry Smith @*/ 1594f8b49ee9SBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx) 15959b94acceSBarry Smith { 159685385478SLisandro Dalcin PetscErrorCode ierr; 15976cab3a1bSJed Brown DM dm; 15986cab3a1bSJed Brown 15993a40ed3dSBarry Smith PetscFunctionBegin; 16000700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1601d2a683ecSLisandro Dalcin if (r) { 1602d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1603d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 160485385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 16056bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 1606f5af7f23SKarl Rupp 160785385478SLisandro Dalcin snes->vec_func = r; 1608d2a683ecSLisandro Dalcin } 16096cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1610f8b49ee9SBarry Smith ierr = DMSNESSetFunction(dm,f,ctx);CHKERRQ(ierr); 16113a40ed3dSBarry Smith PetscFunctionReturn(0); 16129b94acceSBarry Smith } 16139b94acceSBarry Smith 1614646217ecSPeter Brune 1615646217ecSPeter Brune #undef __FUNCT__ 1616e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction" 1617e4ed7901SPeter Brune /*@C 1618e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1619e4ed7901SPeter Brune function norm at the initialization of the method. In some 1620e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1621e4ed7901SPeter Brune SNESSolve. This function allows one to avoid a redundant call 1622e4ed7901SPeter Brune to SNESComputeFunction in that case. 1623e4ed7901SPeter Brune 1624e4ed7901SPeter Brune Logically Collective on SNES 1625e4ed7901SPeter Brune 1626e4ed7901SPeter Brune Input Parameters: 1627e4ed7901SPeter Brune + snes - the SNES context 1628e4ed7901SPeter Brune - f - vector to store function value 1629e4ed7901SPeter Brune 1630e4ed7901SPeter Brune Notes: 1631e4ed7901SPeter Brune This should not be modified during the solution procedure. 1632e4ed7901SPeter Brune 1633e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1634e4ed7901SPeter Brune 1635e4ed7901SPeter Brune Level: developer 1636e4ed7901SPeter Brune 1637e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function 1638e4ed7901SPeter Brune 1639e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm() 1640e4ed7901SPeter Brune @*/ 1641e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1642e4ed7901SPeter Brune { 1643e4ed7901SPeter Brune PetscErrorCode ierr; 1644e4ed7901SPeter Brune Vec vec_func; 1645e4ed7901SPeter Brune 1646e4ed7901SPeter Brune PetscFunctionBegin; 1647e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1648e4ed7901SPeter Brune PetscValidHeaderSpecific(f,VEC_CLASSID,2); 1649e4ed7901SPeter Brune PetscCheckSameComm(snes,1,f,2); 16505c9e203fSPeter Brune if (snes->pcside == PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) { 1651902f982fSPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1652902f982fSPeter Brune PetscFunctionReturn(0); 1653902f982fSPeter Brune } 16540298fd71SBarry Smith ierr = SNESGetFunction(snes,&vec_func,NULL,NULL);CHKERRQ(ierr); 1655e4ed7901SPeter Brune ierr = VecCopy(f, vec_func);CHKERRQ(ierr); 1656f5af7f23SKarl Rupp 1657217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 1658e4ed7901SPeter Brune PetscFunctionReturn(0); 1659e4ed7901SPeter Brune } 1660e4ed7901SPeter Brune 1661e4ed7901SPeter Brune #undef __FUNCT__ 1662365a6726SPeter Brune #define __FUNCT__ "SNESSetNormSchedule" 1663534ebe21SPeter Brune /*@ 1664365a6726SPeter Brune SNESSetNormSchedule - Sets the SNESNormSchedule used in covergence and monitoring 1665534ebe21SPeter Brune of the SNES method. 1666534ebe21SPeter Brune 1667534ebe21SPeter Brune Logically Collective on SNES 1668534ebe21SPeter Brune 1669534ebe21SPeter Brune Input Parameters: 1670534ebe21SPeter Brune + snes - the SNES context 1671365a6726SPeter Brune - normschedule - the frequency of norm computation 1672534ebe21SPeter Brune 1673517f1916SMatthew G. Knepley Options Database Key: 1674517f1916SMatthew G. Knepley . -snes_norm_schedule <none, always, initialonly, finalonly, initalfinalonly> 1675517f1916SMatthew G. Knepley 1676534ebe21SPeter Brune Notes: 1677365a6726SPeter Brune Only certain SNES methods support certain SNESNormSchedules. Most require evaluation 1678534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1679534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1680be95d8f1SBarry Smith (SNESNGS) and the like do not require the norm of the function to be computed, and therfore 1681534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1682534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1683534ebe21SPeter Brune their solution. 1684534ebe21SPeter Brune 1685534ebe21SPeter Brune Level: developer 1686534ebe21SPeter Brune 1687534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1688534ebe21SPeter Brune 1689365a6726SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1690534ebe21SPeter Brune @*/ 1691365a6726SPeter Brune PetscErrorCode SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule) 1692534ebe21SPeter Brune { 1693534ebe21SPeter Brune PetscFunctionBegin; 1694534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1695365a6726SPeter Brune snes->normschedule = normschedule; 1696534ebe21SPeter Brune PetscFunctionReturn(0); 1697534ebe21SPeter Brune } 1698534ebe21SPeter Brune 1699534ebe21SPeter Brune 1700534ebe21SPeter Brune #undef __FUNCT__ 1701365a6726SPeter Brune #define __FUNCT__ "SNESGetNormSchedule" 1702534ebe21SPeter Brune /*@ 1703365a6726SPeter Brune SNESGetNormSchedule - Gets the SNESNormSchedule used in covergence and monitoring 1704534ebe21SPeter Brune of the SNES method. 1705534ebe21SPeter Brune 1706534ebe21SPeter Brune Logically Collective on SNES 1707534ebe21SPeter Brune 1708534ebe21SPeter Brune Input Parameters: 1709534ebe21SPeter Brune + snes - the SNES context 1710365a6726SPeter Brune - normschedule - the type of the norm used 1711534ebe21SPeter Brune 1712534ebe21SPeter Brune Level: advanced 1713534ebe21SPeter Brune 1714534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1715534ebe21SPeter Brune 1716365a6726SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1717534ebe21SPeter Brune @*/ 1718365a6726SPeter Brune PetscErrorCode SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule) 1719534ebe21SPeter Brune { 1720534ebe21SPeter Brune PetscFunctionBegin; 1721534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1722365a6726SPeter Brune *normschedule = snes->normschedule; 1723534ebe21SPeter Brune PetscFunctionReturn(0); 1724534ebe21SPeter Brune } 1725534ebe21SPeter Brune 172647073ea2SPeter Brune 172747073ea2SPeter Brune #undef __FUNCT__ 1728c5ce4427SMatthew G. Knepley #define __FUNCT__ "SNESSetFunctionNorm" 1729c5ce4427SMatthew G. Knepley /*@ 1730c5ce4427SMatthew G. Knepley SNESSetFunctionNorm - Sets the last computed residual norm. 1731c5ce4427SMatthew G. Knepley 1732c5ce4427SMatthew G. Knepley Logically Collective on SNES 1733c5ce4427SMatthew G. Knepley 1734c5ce4427SMatthew G. Knepley Input Parameters: 1735c5ce4427SMatthew G. Knepley + snes - the SNES context 1736c5ce4427SMatthew G. Knepley 1737c5ce4427SMatthew G. Knepley - normschedule - the frequency of norm computation 1738c5ce4427SMatthew G. Knepley 1739c5ce4427SMatthew G. Knepley Level: developer 1740c5ce4427SMatthew G. Knepley 1741c5ce4427SMatthew G. Knepley .keywords: SNES, nonlinear, set, function, norm, type 1742c5ce4427SMatthew G. Knepley .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1743c5ce4427SMatthew G. Knepley @*/ 1744c5ce4427SMatthew G. Knepley PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm) 1745c5ce4427SMatthew G. Knepley { 1746c5ce4427SMatthew G. Knepley PetscFunctionBegin; 1747c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1748c5ce4427SMatthew G. Knepley snes->norm = norm; 1749c5ce4427SMatthew G. Knepley PetscFunctionReturn(0); 1750c5ce4427SMatthew G. Knepley } 1751c5ce4427SMatthew G. Knepley 1752c5ce4427SMatthew G. Knepley #undef __FUNCT__ 1753c5ce4427SMatthew G. Knepley #define __FUNCT__ "SNESGetFunctionNorm" 1754c5ce4427SMatthew G. Knepley /*@ 1755c5ce4427SMatthew G. Knepley SNESGetFunctionNorm - Gets the last computed norm of the residual 1756c5ce4427SMatthew G. Knepley 1757c5ce4427SMatthew G. Knepley Not Collective 1758c5ce4427SMatthew G. Knepley 1759c5ce4427SMatthew G. Knepley Input Parameter: 1760c5ce4427SMatthew G. Knepley . snes - the SNES context 1761c5ce4427SMatthew G. Knepley 1762c5ce4427SMatthew G. Knepley Output Parameter: 1763c5ce4427SMatthew G. Knepley . norm - the last computed residual norm 1764c5ce4427SMatthew G. Knepley 1765c5ce4427SMatthew G. Knepley Level: developer 1766c5ce4427SMatthew G. Knepley 1767c5ce4427SMatthew G. Knepley .keywords: SNES, nonlinear, set, function, norm, type 1768c5ce4427SMatthew G. Knepley .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 1769c5ce4427SMatthew G. Knepley @*/ 1770c5ce4427SMatthew G. Knepley PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm) 1771c5ce4427SMatthew G. Knepley { 1772c5ce4427SMatthew G. Knepley PetscFunctionBegin; 1773c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1774c5ce4427SMatthew G. Knepley PetscValidPointer(norm, 2); 1775c5ce4427SMatthew G. Knepley *norm = snes->norm; 1776c5ce4427SMatthew G. Knepley PetscFunctionReturn(0); 1777c5ce4427SMatthew G. Knepley } 1778c5ce4427SMatthew G. Knepley 1779c5ce4427SMatthew G. Knepley #undef __FUNCT__ 178047073ea2SPeter Brune #define __FUNCT__ "SNESSetFunctionType" 178147073ea2SPeter Brune /*@C 178247073ea2SPeter Brune SNESSetFunctionType - Sets the SNESNormSchedule used in covergence and monitoring 178347073ea2SPeter Brune of the SNES method. 178447073ea2SPeter Brune 178547073ea2SPeter Brune Logically Collective on SNES 178647073ea2SPeter Brune 178747073ea2SPeter Brune Input Parameters: 178847073ea2SPeter Brune + snes - the SNES context 178947073ea2SPeter Brune - normschedule - the frequency of norm computation 179047073ea2SPeter Brune 179147073ea2SPeter Brune Notes: 179247073ea2SPeter Brune Only certain SNES methods support certain SNESNormSchedules. Most require evaluation 179347073ea2SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 179447073ea2SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1795be95d8f1SBarry Smith (SNESNGS) and the like do not require the norm of the function to be computed, and therfore 179647073ea2SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 179747073ea2SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 179847073ea2SPeter Brune their solution. 179947073ea2SPeter Brune 180047073ea2SPeter Brune Level: developer 180147073ea2SPeter Brune 180247073ea2SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 180347073ea2SPeter Brune 180447073ea2SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 180547073ea2SPeter Brune @*/ 180647073ea2SPeter Brune PetscErrorCode SNESSetFunctionType(SNES snes, SNESFunctionType type) 180747073ea2SPeter Brune { 180847073ea2SPeter Brune PetscFunctionBegin; 180947073ea2SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 181047073ea2SPeter Brune snes->functype = type; 181147073ea2SPeter Brune PetscFunctionReturn(0); 181247073ea2SPeter Brune } 181347073ea2SPeter Brune 181447073ea2SPeter Brune 181547073ea2SPeter Brune #undef __FUNCT__ 181647073ea2SPeter Brune #define __FUNCT__ "SNESGetFunctionType" 181747073ea2SPeter Brune /*@C 181847073ea2SPeter Brune SNESGetFunctionType - Gets the SNESNormSchedule used in covergence and monitoring 181947073ea2SPeter Brune of the SNES method. 182047073ea2SPeter Brune 182147073ea2SPeter Brune Logically Collective on SNES 182247073ea2SPeter Brune 182347073ea2SPeter Brune Input Parameters: 182447073ea2SPeter Brune + snes - the SNES context 182547073ea2SPeter Brune - normschedule - the type of the norm used 182647073ea2SPeter Brune 182747073ea2SPeter Brune Level: advanced 182847073ea2SPeter Brune 182947073ea2SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 183047073ea2SPeter Brune 183147073ea2SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule 183247073ea2SPeter Brune @*/ 183347073ea2SPeter Brune PetscErrorCode SNESGetFunctionType(SNES snes, SNESFunctionType *type) 183447073ea2SPeter Brune { 183547073ea2SPeter Brune PetscFunctionBegin; 183647073ea2SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 183747073ea2SPeter Brune *type = snes->functype; 1838534ebe21SPeter Brune PetscFunctionReturn(0); 1839534ebe21SPeter Brune } 1840534ebe21SPeter Brune 1841bf388a1fSBarry Smith /*MC 1842be95d8f1SBarry Smith SNESNGSFunction - function used to convey a Gauss-Seidel sweep on the nonlinear function 1843bf388a1fSBarry Smith 1844bf388a1fSBarry Smith Synopsis: 1845aaa7dc30SBarry Smith #include <petscsnes.h> 1846be95d8f1SBarry Smith $ SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx); 1847bf388a1fSBarry Smith 1848bf388a1fSBarry Smith + X - solution vector 1849bf388a1fSBarry Smith . B - RHS vector 1850bf388a1fSBarry Smith - ctx - optional user-defined Gauss-Seidel context 1851bf388a1fSBarry Smith 1852878cb397SSatish Balay Level: intermediate 1853878cb397SSatish Balay 1854be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESGetNGS() 1855bf388a1fSBarry Smith M*/ 1856bf388a1fSBarry Smith 1857534ebe21SPeter Brune #undef __FUNCT__ 1858be95d8f1SBarry Smith #define __FUNCT__ "SNESSetNGS" 1859c79ef259SPeter Brune /*@C 1860be95d8f1SBarry Smith SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for 1861c79ef259SPeter Brune use with composed nonlinear solvers. 1862c79ef259SPeter Brune 1863c79ef259SPeter Brune Input Parameters: 1864c79ef259SPeter Brune + snes - the SNES context 1865be95d8f1SBarry Smith . f - function evaluation routine to apply Gauss-Seidel see SNESNGSFunction 1866c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 18670298fd71SBarry Smith smoother evaluation routine (may be NULL) 1868c79ef259SPeter Brune 1869c79ef259SPeter Brune Notes: 1870be95d8f1SBarry Smith The NGS routines are used by the composed nonlinear solver to generate 1871c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1872c79ef259SPeter Brune 1873d28543b3SPeter Brune Level: intermediate 1874c79ef259SPeter Brune 1875d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1876c79ef259SPeter Brune 1877be95d8f1SBarry Smith .seealso: SNESGetFunction(), SNESComputeNGS() 1878c79ef259SPeter Brune @*/ 1879be95d8f1SBarry Smith PetscErrorCode SNESSetNGS(SNES snes,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx) 18806cab3a1bSJed Brown { 18816cab3a1bSJed Brown PetscErrorCode ierr; 18826cab3a1bSJed Brown DM dm; 18836cab3a1bSJed Brown 1884646217ecSPeter Brune PetscFunctionBegin; 18856cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 18866cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1887be95d8f1SBarry Smith ierr = DMSNESSetNGS(dm,f,ctx);CHKERRQ(ierr); 1888646217ecSPeter Brune PetscFunctionReturn(0); 1889646217ecSPeter Brune } 1890646217ecSPeter Brune 1891d25893d9SBarry Smith #undef __FUNCT__ 18928b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 189382b59a81SJed Brown PETSC_EXTERN PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 18948b0a5094SBarry Smith { 18958b0a5094SBarry Smith PetscErrorCode ierr; 1896e03ab78fSPeter Brune DM dm; 1897942e3340SBarry Smith DMSNES sdm; 18986cab3a1bSJed Brown 18998b0a5094SBarry Smith PetscFunctionBegin; 1900e03ab78fSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1901942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 19028b0a5094SBarry Smith /* A(x)*x - b(x) */ 190322c6f798SBarry Smith if (sdm->ops->computepfunction) { 190422c6f798SBarry Smith ierr = (*sdm->ops->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr); 190522c6f798SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard function."); 1906e03ab78fSPeter Brune 190722c6f798SBarry Smith if (sdm->ops->computepjacobian) { 1908d1e9a80fSBarry Smith ierr = (*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx);CHKERRQ(ierr); 190974e1e8c1SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard matrix."); 19108b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 191195eabcedSBarry Smith ierr = MatMultAdd(snes->jacobian,x,f,f);CHKERRQ(ierr); 19128b0a5094SBarry Smith PetscFunctionReturn(0); 19138b0a5094SBarry Smith } 19148b0a5094SBarry Smith 19158b0a5094SBarry Smith #undef __FUNCT__ 19168b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 1917d1e9a80fSBarry Smith PETSC_EXTERN PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat J,Mat B,void *ctx) 19188b0a5094SBarry Smith { 19198b0a5094SBarry Smith PetscFunctionBegin; 1920e03ab78fSPeter Brune /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */ 19218b0a5094SBarry Smith PetscFunctionReturn(0); 19228b0a5094SBarry Smith } 19238b0a5094SBarry Smith 19248b0a5094SBarry Smith #undef __FUNCT__ 19258b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 19268b0a5094SBarry Smith /*@C 19270d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 19288b0a5094SBarry Smith 19298b0a5094SBarry Smith Logically Collective on SNES 19308b0a5094SBarry Smith 19318b0a5094SBarry Smith Input Parameters: 19328b0a5094SBarry Smith + snes - the SNES context 19338b0a5094SBarry Smith . r - vector to store function value 1934f8b49ee9SBarry Smith . b - function evaluation routine 1935e5d3d808SBarry Smith . Amat - matrix with which A(x) x - b(x) is to be computed 1936e5d3d808SBarry Smith . Pmat - matrix from which preconditioner is computed (usually the same as Amat) 1937411c0326SBarry Smith . J - function to compute matrix value, see SNESJacobianFunction for details on its calling sequence 19388b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 19390298fd71SBarry Smith function evaluation routine (may be NULL) 19408b0a5094SBarry Smith 19418b0a5094SBarry Smith Notes: 1942f450aa47SBarry 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 1943f450aa47SBarry 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. 1944f450aa47SBarry Smith 19458b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 19468b0a5094SBarry Smith 19478b0a5094SBarry 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} 19488b0a5094SBarry 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. 19498b0a5094SBarry Smith 19508b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 19518b0a5094SBarry Smith 19520d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 19530d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 19548b0a5094SBarry Smith 19558b0a5094SBarry 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 19568b0a5094SBarry 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 19578b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 19588b0a5094SBarry Smith 1959f450aa47SBarry Smith Level: intermediate 19608b0a5094SBarry Smith 19618b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 19628b0a5094SBarry Smith 1963411c0326SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard(), SNESJacobianFunction 19648b0a5094SBarry Smith @*/ 1965d1e9a80fSBarry 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) 19668b0a5094SBarry Smith { 19678b0a5094SBarry Smith PetscErrorCode ierr; 1968e03ab78fSPeter Brune DM dm; 1969e03ab78fSPeter Brune 19708b0a5094SBarry Smith PetscFunctionBegin; 19718b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1972e03ab78fSPeter Brune ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 1973f8b49ee9SBarry Smith ierr = DMSNESSetPicard(dm,b,J,ctx);CHKERRQ(ierr); 19748b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 1975e5d3d808SBarry Smith ierr = SNESSetJacobian(snes,Amat,Pmat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 19768b0a5094SBarry Smith PetscFunctionReturn(0); 19778b0a5094SBarry Smith } 19788b0a5094SBarry Smith 19797971a8bfSPeter Brune #undef __FUNCT__ 19807971a8bfSPeter Brune #define __FUNCT__ "SNESGetPicard" 19817971a8bfSPeter Brune /*@C 19827971a8bfSPeter Brune SNESGetPicard - Returns the context for the Picard iteration 19837971a8bfSPeter Brune 19847971a8bfSPeter Brune Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 19857971a8bfSPeter Brune 19867971a8bfSPeter Brune Input Parameter: 19877971a8bfSPeter Brune . snes - the SNES context 19887971a8bfSPeter Brune 19897971a8bfSPeter Brune Output Parameter: 19900298fd71SBarry Smith + r - the function (or NULL) 1991f8b49ee9SBarry Smith . f - the function (or NULL); see SNESFunction for calling sequence details 1992e4357dc4SBarry Smith . Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL) 1993e4357dc4SBarry Smith . Pmat - the matrix from which the preconditioner will be constructed (or NULL) 1994f8b49ee9SBarry Smith . J - the function for matrix evaluation (or NULL); see SNESJacobianFunction for calling sequence details 19950298fd71SBarry Smith - ctx - the function context (or NULL) 19967971a8bfSPeter Brune 19977971a8bfSPeter Brune Level: advanced 19987971a8bfSPeter Brune 19997971a8bfSPeter Brune .keywords: SNES, nonlinear, get, function 20007971a8bfSPeter Brune 2001e4357dc4SBarry Smith .seealso: SNESSetPicard(), SNESGetFunction(), SNESGetJacobian(), SNESGetDM(), SNESFunction, SNESJacobianFunction 20027971a8bfSPeter Brune @*/ 2003d1e9a80fSBarry 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) 20047971a8bfSPeter Brune { 20057971a8bfSPeter Brune PetscErrorCode ierr; 20067971a8bfSPeter Brune DM dm; 20077971a8bfSPeter Brune 20087971a8bfSPeter Brune PetscFunctionBegin; 20097971a8bfSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 20100298fd71SBarry Smith ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 2011e4357dc4SBarry Smith ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 20127971a8bfSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2013f8b49ee9SBarry Smith ierr = DMSNESGetPicard(dm,f,J,ctx);CHKERRQ(ierr); 20147971a8bfSPeter Brune PetscFunctionReturn(0); 20157971a8bfSPeter Brune } 20167971a8bfSPeter Brune 20178b0a5094SBarry Smith #undef __FUNCT__ 2018d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 2019d25893d9SBarry Smith /*@C 2020d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 2021d25893d9SBarry Smith 2022d25893d9SBarry Smith Logically Collective on SNES 2023d25893d9SBarry Smith 2024d25893d9SBarry Smith Input Parameters: 2025d25893d9SBarry Smith + snes - the SNES context 2026d25893d9SBarry Smith . func - function evaluation routine 2027d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 20280298fd71SBarry Smith function evaluation routine (may be NULL) 2029d25893d9SBarry Smith 2030d25893d9SBarry Smith Calling sequence of func: 2031d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 2032d25893d9SBarry Smith 2033d25893d9SBarry Smith . f - function vector 2034d25893d9SBarry Smith - ctx - optional user-defined function context 2035d25893d9SBarry Smith 2036d25893d9SBarry Smith Level: intermediate 2037d25893d9SBarry Smith 2038d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 2039d25893d9SBarry Smith 2040d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 2041d25893d9SBarry Smith @*/ 2042d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 2043d25893d9SBarry Smith { 2044d25893d9SBarry Smith PetscFunctionBegin; 2045d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2046d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 2047d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 2048d25893d9SBarry Smith PetscFunctionReturn(0); 2049d25893d9SBarry Smith } 2050d25893d9SBarry Smith 20513ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 20523ab0aad5SBarry Smith #undef __FUNCT__ 20531096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 20541096aae1SMatthew Knepley /*@C 20551096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 20561096aae1SMatthew Knepley it assumes a zero right hand side. 20571096aae1SMatthew Knepley 20583f9fe445SBarry Smith Logically Collective on SNES 20591096aae1SMatthew Knepley 20601096aae1SMatthew Knepley Input Parameter: 20611096aae1SMatthew Knepley . snes - the SNES context 20621096aae1SMatthew Knepley 20631096aae1SMatthew Knepley Output Parameter: 20640298fd71SBarry Smith . rhs - the right hand side vector or NULL if the right hand side vector is null 20651096aae1SMatthew Knepley 20661096aae1SMatthew Knepley Level: intermediate 20671096aae1SMatthew Knepley 20681096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 20691096aae1SMatthew Knepley 207085385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 20711096aae1SMatthew Knepley @*/ 20727087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 20731096aae1SMatthew Knepley { 20741096aae1SMatthew Knepley PetscFunctionBegin; 20750700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 20761096aae1SMatthew Knepley PetscValidPointer(rhs,2); 207785385478SLisandro Dalcin *rhs = snes->vec_rhs; 20781096aae1SMatthew Knepley PetscFunctionReturn(0); 20791096aae1SMatthew Knepley } 20801096aae1SMatthew Knepley 20811096aae1SMatthew Knepley #undef __FUNCT__ 20824a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 20839b94acceSBarry Smith /*@ 2084bf388a1fSBarry Smith SNESComputeFunction - Calls the function that has been set with SNESSetFunction(). 20859b94acceSBarry Smith 2086c7afd0dbSLois Curfman McInnes Collective on SNES 2087c7afd0dbSLois Curfman McInnes 20889b94acceSBarry Smith Input Parameters: 2089c7afd0dbSLois Curfman McInnes + snes - the SNES context 2090c7afd0dbSLois Curfman McInnes - x - input vector 20919b94acceSBarry Smith 20929b94acceSBarry Smith Output Parameter: 20933638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 20949b94acceSBarry Smith 20951bffabb2SLois Curfman McInnes Notes: 209636851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 209736851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 209836851e7fSLois Curfman McInnes themselves. 209936851e7fSLois Curfman McInnes 210036851e7fSLois Curfman McInnes Level: developer 210136851e7fSLois Curfman McInnes 21029b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 21039b94acceSBarry Smith 2104a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 21059b94acceSBarry Smith @*/ 21067087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 21079b94acceSBarry Smith { 2108dfbe8321SBarry Smith PetscErrorCode ierr; 21096cab3a1bSJed Brown DM dm; 2110942e3340SBarry Smith DMSNES sdm; 21119b94acceSBarry Smith 21123a40ed3dSBarry Smith PetscFunctionBegin; 21130700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 21140700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 21150700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2116c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 2117c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 211862796dfbSBarry Smith ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr); 2119184914b5SBarry Smith 21206cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2121942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 212232f3f7c2SPeter Brune if (sdm->ops->computefunction) { 212394db00ebSBarry Smith if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) { 2124ccf3c845SPeter Brune ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 212594db00ebSBarry Smith } 21265edff71fSBarry Smith ierr = VecLockPush(x);CHKERRQ(ierr); 2127d64ed03dSBarry Smith PetscStackPush("SNES user function"); 212822c6f798SBarry Smith ierr = (*sdm->ops->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 2129d64ed03dSBarry Smith PetscStackPop; 21305edff71fSBarry Smith ierr = VecLockPop(x);CHKERRQ(ierr); 213194db00ebSBarry Smith if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) { 2132ccf3c845SPeter Brune ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 213394db00ebSBarry Smith } 2134c90fad12SPeter Brune } else if (snes->vec_rhs) { 2135c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 2136644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 213785385478SLisandro Dalcin if (snes->vec_rhs) { 213885385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 21393ab0aad5SBarry Smith } 2140ae3c334cSLois Curfman McInnes snes->nfuncs++; 2141422a814eSBarry Smith /* 2142422a814eSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2143422a814eSBarry Smith propagate the value to all processes 2144422a814eSBarry Smith */ 2145422a814eSBarry Smith if (snes->domainerror) { 2146422a814eSBarry Smith ierr = VecSetInf(y);CHKERRQ(ierr); 2147422a814eSBarry Smith } 21483a40ed3dSBarry Smith PetscFunctionReturn(0); 21499b94acceSBarry Smith } 21509b94acceSBarry Smith 21514a2ae208SSatish Balay #undef __FUNCT__ 2152be95d8f1SBarry Smith #define __FUNCT__ "SNESComputeNGS" 2153c79ef259SPeter Brune /*@ 2154be95d8f1SBarry Smith SNESComputeNGS - Calls the Gauss-Seidel function that has been set with SNESSetNGS(). 2155c79ef259SPeter Brune 2156c79ef259SPeter Brune Collective on SNES 2157c79ef259SPeter Brune 2158c79ef259SPeter Brune Input Parameters: 2159c79ef259SPeter Brune + snes - the SNES context 2160c79ef259SPeter Brune . x - input vector 2161c79ef259SPeter Brune - b - rhs vector 2162c79ef259SPeter Brune 2163c79ef259SPeter Brune Output Parameter: 2164c79ef259SPeter Brune . x - new solution vector 2165c79ef259SPeter Brune 2166c79ef259SPeter Brune Notes: 2167be95d8f1SBarry Smith SNESComputeNGS() is typically used within composed nonlinear solver 2168c79ef259SPeter Brune implementations, so most users would not generally call this routine 2169c79ef259SPeter Brune themselves. 2170c79ef259SPeter Brune 2171c79ef259SPeter Brune Level: developer 2172c79ef259SPeter Brune 2173c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 2174c79ef259SPeter Brune 2175be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESComputeFunction() 2176c79ef259SPeter Brune @*/ 2177be95d8f1SBarry Smith PetscErrorCode SNESComputeNGS(SNES snes,Vec b,Vec x) 2178646217ecSPeter Brune { 2179646217ecSPeter Brune PetscErrorCode ierr; 21806cab3a1bSJed Brown DM dm; 2181942e3340SBarry Smith DMSNES sdm; 2182646217ecSPeter Brune 2183646217ecSPeter Brune PetscFunctionBegin; 2184646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2185646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2186646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 2187646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 2188646217ecSPeter Brune if (b) PetscCheckSameComm(snes,1,b,3); 218962796dfbSBarry Smith if (b) {ierr = VecValidValues(b,2,PETSC_TRUE);CHKERRQ(ierr);} 2190be95d8f1SBarry Smith ierr = PetscLogEventBegin(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr); 21916cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2192942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 219322c6f798SBarry Smith if (sdm->ops->computegs) { 21945edff71fSBarry Smith if (b) {ierr = VecLockPush(b);CHKERRQ(ierr);} 2195be95d8f1SBarry Smith PetscStackPush("SNES user NGS"); 219622c6f798SBarry Smith ierr = (*sdm->ops->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 2197646217ecSPeter Brune PetscStackPop; 21985edff71fSBarry Smith if (b) {ierr = VecLockPop(b);CHKERRQ(ierr);} 2199be95d8f1SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve()."); 2200be95d8f1SBarry Smith ierr = PetscLogEventEnd(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr); 2201646217ecSPeter Brune PetscFunctionReturn(0); 2202646217ecSPeter Brune } 2203646217ecSPeter Brune 2204646217ecSPeter Brune #undef __FUNCT__ 22054a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 220662fef451SLois Curfman McInnes /*@ 2207bf388a1fSBarry Smith SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian(). 220862fef451SLois Curfman McInnes 2209c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 2210c7afd0dbSLois Curfman McInnes 221162fef451SLois Curfman McInnes Input Parameters: 2212c7afd0dbSLois Curfman McInnes + snes - the SNES context 2213c7afd0dbSLois Curfman McInnes - x - input vector 221462fef451SLois Curfman McInnes 221562fef451SLois Curfman McInnes Output Parameters: 2216c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 2217d1e9a80fSBarry Smith - B - optional preconditioning matrix 2218fee21e36SBarry Smith 2219e35cf81dSBarry Smith Options Database Keys: 2220e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 2221693365a8SJed Brown . -snes_lag_jacobian <lag> 2222693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 2223693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 2224693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 22254c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 2226c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 2227c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 2228c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 2229c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2230c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 22314c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 2232c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 2233c01495d3SJed Brown 2234e35cf81dSBarry Smith 223562fef451SLois Curfman McInnes Notes: 223662fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 223762fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 223862fef451SLois Curfman McInnes 223936851e7fSLois Curfman McInnes Level: developer 224036851e7fSLois Curfman McInnes 224162fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 224262fef451SLois Curfman McInnes 2243e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 224462fef451SLois Curfman McInnes @*/ 2245d1e9a80fSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat A,Mat B) 22469b94acceSBarry Smith { 2247dfbe8321SBarry Smith PetscErrorCode ierr; 2248ace3abfcSBarry Smith PetscBool flag; 22496cab3a1bSJed Brown DM dm; 2250942e3340SBarry Smith DMSNES sdm; 2251e0e3a89bSBarry Smith KSP ksp; 22523a40ed3dSBarry Smith 22533a40ed3dSBarry Smith PetscFunctionBegin; 22540700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 22550700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2256c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 225762796dfbSBarry Smith ierr = VecValidValues(X,2,PETSC_TRUE);CHKERRQ(ierr); 22586cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2259942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 22603232da50SPeter Brune 2261ce94432eSBarry Smith if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 2262ebd3b9afSBarry Smith 2263ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 2264ebd3b9afSBarry Smith 2265fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 2266fe3ffe1eSBarry Smith snes->lagjacobian = -1; 2267f5af7f23SKarl Rupp 2268fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 2269fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 2270e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 227194ab13aaSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr); 2272ebd3b9afSBarry Smith if (flag) { 227394ab13aaSBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 227494ab13aaSBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2275ebd3b9afSBarry Smith } 2276e35cf81dSBarry Smith PetscFunctionReturn(0); 227737ec4e1aSPeter Brune } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) { 2278e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 227994ab13aaSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr); 2280ebd3b9afSBarry Smith if (flag) { 228194ab13aaSBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 228294ab13aaSBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2283ebd3b9afSBarry Smith } 2284e35cf81dSBarry Smith PetscFunctionReturn(0); 2285e35cf81dSBarry Smith } 2286d728fb7dSPeter Brune if (snes->pc && snes->pcside == PC_LEFT) { 228794ab13aaSBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 228894ab13aaSBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2289d728fb7dSPeter Brune PetscFunctionReturn(0); 2290d728fb7dSPeter Brune } 2291e35cf81dSBarry Smith 229294ab13aaSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr); 22935edff71fSBarry Smith ierr = VecLockPush(X);CHKERRQ(ierr); 2294d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 2295d1e9a80fSBarry Smith ierr = (*sdm->ops->computejacobian)(snes,X,A,B,sdm->jacobianctx);CHKERRQ(ierr); 2296d64ed03dSBarry Smith PetscStackPop; 22975edff71fSBarry Smith ierr = VecLockPop(X);CHKERRQ(ierr); 229894ab13aaSBarry Smith ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr); 2299a8054027SBarry Smith 2300e0e3a89bSBarry Smith /* the next line ensures that snes->ksp exists */ 2301e0e3a89bSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 23023b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 23033b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 2304d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr); 23053b4f5425SBarry Smith snes->lagpreconditioner = -1; 23063b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 2307a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 2308d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr); 230937ec4e1aSPeter Brune } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) { 2310a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 2311d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr); 2312d1e9a80fSBarry Smith } else { 2313d1e9a80fSBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner\n");CHKERRQ(ierr); 2314d1e9a80fSBarry Smith ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr); 2315a8054027SBarry Smith } 2316a8054027SBarry Smith 23176d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 231894ab13aaSBarry Smith /* PetscValidHeaderSpecific(A,MAT_CLASSID,3); 231994ab13aaSBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,4); */ 2320693365a8SJed Brown { 2321693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 23220298fd71SBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,NULL);CHKERRQ(ierr); 23230298fd71SBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,NULL);CHKERRQ(ierr); 23240298fd71SBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,NULL);CHKERRQ(ierr); 23250298fd71SBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,NULL);CHKERRQ(ierr); 2326693365a8SJed Brown if (flag || flag_draw || flag_contour) { 23270298fd71SBarry Smith Mat Bexp_mine = NULL,Bexp,FDexp; 2328693365a8SJed Brown PetscViewer vdraw,vstdout; 23296b3a5b13SJed Brown PetscBool flg; 2330693365a8SJed Brown if (flag_operator) { 233194ab13aaSBarry Smith ierr = MatComputeExplicitOperator(A,&Bexp_mine);CHKERRQ(ierr); 2332693365a8SJed Brown Bexp = Bexp_mine; 2333693365a8SJed Brown } else { 2334693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 233594ab13aaSBarry Smith ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 233694ab13aaSBarry Smith if (flg) Bexp = B; 2337693365a8SJed Brown else { 2338693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 233994ab13aaSBarry Smith ierr = MatComputeExplicitOperator(B,&Bexp_mine);CHKERRQ(ierr); 2340693365a8SJed Brown Bexp = Bexp_mine; 2341693365a8SJed Brown } 2342693365a8SJed Brown } 2343693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 2344d1e9a80fSBarry Smith ierr = SNESComputeJacobianDefault(snes,X,FDexp,FDexp,NULL);CHKERRQ(ierr); 2345ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr); 2346693365a8SJed Brown if (flag_draw || flag_contour) { 2347ce94432eSBarry Smith ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2348693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 23490298fd71SBarry Smith } else vdraw = NULL; 2350693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian");CHKERRQ(ierr); 2351693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 2352693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 2353693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 2354693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2355693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 2356693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2357693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 2358693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2359693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 2360693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2361693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 2362693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2363693365a8SJed Brown } 2364693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2365693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2366693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 2367693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 2368693365a8SJed Brown } 2369693365a8SJed Brown } 23704c30e9fbSJed Brown { 23716719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 23726719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 23730298fd71SBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,NULL);CHKERRQ(ierr); 23740298fd71SBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,NULL);CHKERRQ(ierr); 23750298fd71SBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,NULL);CHKERRQ(ierr); 23760298fd71SBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,NULL);CHKERRQ(ierr); 23770298fd71SBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,NULL);CHKERRQ(ierr); 23780298fd71SBarry Smith ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL);CHKERRQ(ierr); 23790298fd71SBarry Smith ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL);CHKERRQ(ierr); 23806719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 23814c30e9fbSJed Brown Mat Bfd; 23824c30e9fbSJed Brown PetscViewer vdraw,vstdout; 2383335efc43SPeter Brune MatColoring coloring; 23844c30e9fbSJed Brown ISColoring iscoloring; 23854c30e9fbSJed Brown MatFDColoring matfdcoloring; 23864c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 23874c30e9fbSJed Brown void *funcctx; 23886719d8e4SJed Brown PetscReal norm1,norm2,normmax; 23894c30e9fbSJed Brown 239094ab13aaSBarry Smith ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 2391335efc43SPeter Brune ierr = MatColoringCreate(Bfd,&coloring);CHKERRQ(ierr); 2392335efc43SPeter Brune ierr = MatColoringSetType(coloring,MATCOLORINGSL);CHKERRQ(ierr); 2393335efc43SPeter Brune ierr = MatColoringSetFromOptions(coloring);CHKERRQ(ierr); 2394335efc43SPeter Brune ierr = MatColoringApply(coloring,&iscoloring);CHKERRQ(ierr); 2395335efc43SPeter Brune ierr = MatColoringDestroy(&coloring);CHKERRQ(ierr); 23964c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 2397f86b9fbaSHong Zhang ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 2398f86b9fbaSHong Zhang ierr = MatFDColoringSetUp(Bfd,iscoloring,matfdcoloring);CHKERRQ(ierr); 23994c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 24004c30e9fbSJed Brown 24014c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 24020298fd71SBarry Smith ierr = SNESGetFunction(snes,NULL,&func,&funcctx);CHKERRQ(ierr); 24034c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr); 24044c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 24054c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 24064c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 2407d1e9a80fSBarry Smith ierr = MatFDColoringApply(Bfd,matfdcoloring,X,snes);CHKERRQ(ierr); 24084c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 24094c30e9fbSJed Brown 2410ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr); 24114c30e9fbSJed Brown if (flag_draw || flag_contour) { 2412ce94432eSBarry Smith ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 24134c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 24140298fd71SBarry Smith } else vdraw = NULL; 24154c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 241694ab13aaSBarry Smith if (flag_display) {ierr = MatView(B,vstdout);CHKERRQ(ierr);} 241794ab13aaSBarry Smith if (vdraw) {ierr = MatView(B,vdraw);CHKERRQ(ierr);} 24184c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 24196719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 24204c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 242194ab13aaSBarry Smith ierr = MatAYPX(Bfd,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 24224c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 24236719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 24244c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 242557622a8eSBarry 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); 24266719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 24274c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 24284c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 24294c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 24304c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 24314c30e9fbSJed Brown } 24324c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 24336719d8e4SJed Brown 24346719d8e4SJed Brown if (flag_threshold) { 24356719d8e4SJed Brown PetscInt bs,rstart,rend,i; 243694ab13aaSBarry Smith ierr = MatGetBlockSize(B,&bs);CHKERRQ(ierr); 243794ab13aaSBarry Smith ierr = MatGetOwnershipRange(B,&rstart,&rend);CHKERRQ(ierr); 24386719d8e4SJed Brown for (i=rstart; i<rend; i++) { 24396719d8e4SJed Brown const PetscScalar *ba,*ca; 24406719d8e4SJed Brown const PetscInt *bj,*cj; 24416719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 24426719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 244394ab13aaSBarry Smith ierr = MatGetRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr); 24446719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 244594ab13aaSBarry Smith if (bn != cn) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 24466719d8e4SJed Brown for (j=0; j<bn; j++) { 24476719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 24486719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 24496719d8e4SJed Brown maxentrycol = bj[j]; 24506719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 24516719d8e4SJed Brown } 24526719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 24536719d8e4SJed Brown maxdiffcol = bj[j]; 24546719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 24556719d8e4SJed Brown } 24566719d8e4SJed Brown if (rdiff > maxrdiff) { 24576719d8e4SJed Brown maxrdiffcol = bj[j]; 24586719d8e4SJed Brown maxrdiff = rdiff; 24596719d8e4SJed Brown } 24606719d8e4SJed Brown } 24616719d8e4SJed Brown if (maxrdiff > 1) { 246257622a8eSBarry 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); 24636719d8e4SJed Brown for (j=0; j<bn; j++) { 24646719d8e4SJed Brown PetscReal rdiff; 24656719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 24666719d8e4SJed Brown if (rdiff > 1) { 246757622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(vstdout," (%D,%g:%g)",bj[j],(double)PetscRealPart(ba[j]),(double)PetscRealPart(ca[j]));CHKERRQ(ierr); 24686719d8e4SJed Brown } 24696719d8e4SJed Brown } 24706719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 24716719d8e4SJed Brown } 247294ab13aaSBarry Smith ierr = MatRestoreRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr); 24736719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 24746719d8e4SJed Brown } 24756719d8e4SJed Brown } 24764c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 24774c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 24784c30e9fbSJed Brown } 24794c30e9fbSJed Brown } 24803a40ed3dSBarry Smith PetscFunctionReturn(0); 24819b94acceSBarry Smith } 24829b94acceSBarry Smith 2483bf388a1fSBarry Smith /*MC 2484411c0326SBarry Smith SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES 2485bf388a1fSBarry Smith 2486bf388a1fSBarry Smith Synopsis: 2487411c0326SBarry Smith #include "petscsnes.h" 2488411c0326SBarry Smith PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx); 2489bf388a1fSBarry Smith 2490bf388a1fSBarry Smith + x - input vector 2491e5d3d808SBarry Smith . Amat - the matrix that defines the (approximate) Jacobian 2492e5d3d808SBarry Smith . Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 2493bf388a1fSBarry Smith - ctx - [optional] user-defined Jacobian context 2494bf388a1fSBarry Smith 2495878cb397SSatish Balay Level: intermediate 2496878cb397SSatish Balay 2497bf388a1fSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction(), SNESSetJacobian(), SNESGetJacobian() 2498bf388a1fSBarry Smith M*/ 2499bf388a1fSBarry Smith 25004a2ae208SSatish Balay #undef __FUNCT__ 25014a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 25029b94acceSBarry Smith /*@C 25039b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2504044dda88SLois Curfman McInnes location to store the matrix. 25059b94acceSBarry Smith 25063f9fe445SBarry Smith Logically Collective on SNES and Mat 2507c7afd0dbSLois Curfman McInnes 25089b94acceSBarry Smith Input Parameters: 2509c7afd0dbSLois Curfman McInnes + snes - the SNES context 2510e5d3d808SBarry Smith . Amat - the matrix that defines the (approximate) Jacobian 2511e5d3d808SBarry Smith . Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 2512411c0326SBarry Smith . J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details 2513c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 25140298fd71SBarry Smith Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value) 25159b94acceSBarry Smith 25169b94acceSBarry Smith Notes: 2517e5d3d808SBarry Smith If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on 251816913363SBarry Smith each matrix. 251916913363SBarry Smith 2520895c21f2SBarry Smith If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null 2521895c21f2SBarry Smith space to Amat and the KSP solvers will automatically use that null space as needed during the solution process. 2522895c21f2SBarry Smith 25238d359177SBarry Smith If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument 2524a8a26c1eSJed Brown must be a MatFDColoring. 2525a8a26c1eSJed Brown 2526c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2527c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2528c3cc8fd1SJed Brown 252936851e7fSLois Curfman McInnes Level: beginner 253036851e7fSLois Curfman McInnes 25319b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 25329b94acceSBarry Smith 2533411c0326SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESComputeJacobianDefaultColor(), MatStructure, J, 2534411c0326SBarry Smith SNESSetPicard(), SNESJacobianFunction 25359b94acceSBarry Smith @*/ 2536d1e9a80fSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx) 25379b94acceSBarry Smith { 2538dfbe8321SBarry Smith PetscErrorCode ierr; 25396cab3a1bSJed Brown DM dm; 25403a7fca6bSBarry Smith 25413a40ed3dSBarry Smith PetscFunctionBegin; 25420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2543e5d3d808SBarry Smith if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 2544e5d3d808SBarry Smith if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 2545e5d3d808SBarry Smith if (Amat) PetscCheckSameComm(snes,1,Amat,2); 2546e5d3d808SBarry Smith if (Pmat) PetscCheckSameComm(snes,1,Pmat,3); 25476cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2548f8b49ee9SBarry Smith ierr = DMSNESSetJacobian(dm,J,ctx);CHKERRQ(ierr); 2549e5d3d808SBarry Smith if (Amat) { 2550e5d3d808SBarry Smith ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 25516bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 2552f5af7f23SKarl Rupp 2553e5d3d808SBarry Smith snes->jacobian = Amat; 25543a7fca6bSBarry Smith } 2555e5d3d808SBarry Smith if (Pmat) { 2556e5d3d808SBarry Smith ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr); 25576bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2558f5af7f23SKarl Rupp 2559e5d3d808SBarry Smith snes->jacobian_pre = Pmat; 25603a7fca6bSBarry Smith } 25613a40ed3dSBarry Smith PetscFunctionReturn(0); 25629b94acceSBarry Smith } 256362fef451SLois Curfman McInnes 25644a2ae208SSatish Balay #undef __FUNCT__ 25654a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 2566c2aafc4cSSatish Balay /*@C 2567b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2568b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2569b4fd4287SBarry Smith 2570c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2571c7afd0dbSLois Curfman McInnes 2572b4fd4287SBarry Smith Input Parameter: 2573b4fd4287SBarry Smith . snes - the nonlinear solver context 2574b4fd4287SBarry Smith 2575b4fd4287SBarry Smith Output Parameters: 2576e5d3d808SBarry Smith + Amat - location to stash (approximate) Jacobian matrix (or NULL) 2577e5d3d808SBarry Smith . Pmat - location to stash matrix used to compute the preconditioner (or NULL) 2578411c0326SBarry Smith . J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence 25790298fd71SBarry Smith - ctx - location to stash Jacobian ctx (or NULL) 2580fee21e36SBarry Smith 258136851e7fSLois Curfman McInnes Level: advanced 258236851e7fSLois Curfman McInnes 2583411c0326SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian(), SNESJacobianFunction, SNESGetFunction() 2584b4fd4287SBarry Smith @*/ 2585d1e9a80fSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx) 2586b4fd4287SBarry Smith { 25876cab3a1bSJed Brown PetscErrorCode ierr; 25886cab3a1bSJed Brown DM dm; 2589942e3340SBarry Smith DMSNES sdm; 25906cab3a1bSJed Brown 25913a40ed3dSBarry Smith PetscFunctionBegin; 25920700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2593e5d3d808SBarry Smith if (Amat) *Amat = snes->jacobian; 2594e5d3d808SBarry Smith if (Pmat) *Pmat = snes->jacobian_pre; 25956cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2596942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 2597f8b49ee9SBarry Smith if (J) *J = sdm->ops->computejacobian; 25986cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 25993a40ed3dSBarry Smith PetscFunctionReturn(0); 2600b4fd4287SBarry Smith } 2601b4fd4287SBarry Smith 26024a2ae208SSatish Balay #undef __FUNCT__ 26034a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 26049b94acceSBarry Smith /*@ 26059b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2606272ac6f2SLois Curfman McInnes of a nonlinear solver. 26079b94acceSBarry Smith 2608fee21e36SBarry Smith Collective on SNES 2609fee21e36SBarry Smith 2610c7afd0dbSLois Curfman McInnes Input Parameters: 261170e92668SMatthew Knepley . snes - the SNES context 2612c7afd0dbSLois Curfman McInnes 2613272ac6f2SLois Curfman McInnes Notes: 2614272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2615272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2616272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2617272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2618272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2619272ac6f2SLois Curfman McInnes 262036851e7fSLois Curfman McInnes Level: advanced 262136851e7fSLois Curfman McInnes 26229b94acceSBarry Smith .keywords: SNES, nonlinear, setup 26239b94acceSBarry Smith 26249b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 26259b94acceSBarry Smith @*/ 26267087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 26279b94acceSBarry Smith { 2628dfbe8321SBarry Smith PetscErrorCode ierr; 26296cab3a1bSJed Brown DM dm; 2630942e3340SBarry Smith DMSNES sdm; 2631c35f09e5SBarry Smith SNESLineSearch linesearch, pclinesearch; 26326e2a1849SPeter Brune void *lsprectx,*lspostctx; 26336b2b7091SBarry Smith PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*); 26346b2b7091SBarry Smith PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*); 26356e2a1849SPeter Brune PetscErrorCode (*func)(SNES,Vec,Vec,void*); 26366e2a1849SPeter Brune Vec f,fpc; 26376e2a1849SPeter Brune void *funcctx; 2638d1e9a80fSBarry Smith PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*); 26391eb13d49SPeter Brune void *jacctx,*appctx; 264032b97717SPeter Brune Mat j,jpre; 26413a40ed3dSBarry Smith 26423a40ed3dSBarry Smith PetscFunctionBegin; 26430700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 26444dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 26459b94acceSBarry Smith 26467adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 264704d7464bSBarry Smith ierr = SNESSetType(snes,SNESNEWTONLS);CHKERRQ(ierr); 264885385478SLisandro Dalcin } 264985385478SLisandro Dalcin 26500298fd71SBarry Smith ierr = SNESGetFunction(snes,&snes->vec_func,NULL,NULL);CHKERRQ(ierr); 265158c9b817SLisandro Dalcin 26526cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2653942e3340SBarry Smith ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 2654ce94432eSBarry Smith if (!sdm->ops->computefunction) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object"); 265522c6f798SBarry Smith if (!sdm->ops->computejacobian) { 26568d359177SBarry Smith ierr = DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr); 265719f7a02aSBarry Smith } 26586cab3a1bSJed Brown if (!snes->vec_func) { 26596cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2660214df951SJed Brown } 2661efd51863SBarry Smith 266222d28d08SBarry Smith if (!snes->ksp) { 266322d28d08SBarry Smith ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr); 266422d28d08SBarry Smith } 2665b710008aSBarry Smith 266622d28d08SBarry Smith if (!snes->linesearch) { 26677601faf0SJed Brown ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 266822d28d08SBarry Smith } 2669ed07d7d7SPeter Brune ierr = SNESLineSearchSetFunction(snes->linesearch,SNESComputeFunction);CHKERRQ(ierr); 26709e764e56SPeter Brune 2671172a4300SPeter Brune if (snes->pc && (snes->pcside == PC_LEFT)) { 2672172a4300SPeter Brune snes->mf = PETSC_TRUE; 2673172a4300SPeter Brune snes->mf_operator = PETSC_FALSE; 2674172a4300SPeter Brune } 2675d8f46077SPeter Brune 26766e2a1849SPeter Brune if (snes->pc) { 26776e2a1849SPeter Brune /* copy the DM over */ 26786e2a1849SPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 26796e2a1849SPeter Brune ierr = SNESSetDM(snes->pc,dm);CHKERRQ(ierr); 26806e2a1849SPeter Brune 26816e2a1849SPeter Brune ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr); 26826e2a1849SPeter Brune ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr); 26836e2a1849SPeter Brune ierr = SNESSetFunction(snes->pc,fpc,func,funcctx);CHKERRQ(ierr); 268432b97717SPeter Brune ierr = SNESGetJacobian(snes,&j,&jpre,&jac,&jacctx);CHKERRQ(ierr); 268532b97717SPeter Brune ierr = SNESSetJacobian(snes->pc,j,jpre,jac,jacctx);CHKERRQ(ierr); 26861eb13d49SPeter Brune ierr = SNESGetApplicationContext(snes,&appctx);CHKERRQ(ierr); 26871eb13d49SPeter Brune ierr = SNESSetApplicationContext(snes->pc,appctx);CHKERRQ(ierr); 26886e2a1849SPeter Brune ierr = VecDestroy(&fpc);CHKERRQ(ierr); 26896e2a1849SPeter Brune 26906e2a1849SPeter Brune /* copy the function pointers over */ 26916e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr); 26926e2a1849SPeter Brune 26936e2a1849SPeter Brune /* default to 1 iteration */ 2694140836e4SPeter Brune ierr = SNESSetTolerances(snes->pc,0.0,0.0,0.0,1,snes->pc->max_funcs);CHKERRQ(ierr); 2695a9936a0cSPeter Brune if (snes->pcside==PC_RIGHT) { 2696365a6726SPeter Brune ierr = SNESSetNormSchedule(snes->pc,SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); 2697a9936a0cSPeter Brune } else { 2698365a6726SPeter Brune ierr = SNESSetNormSchedule(snes->pc,SNES_NORM_NONE);CHKERRQ(ierr); 2699a9936a0cSPeter Brune } 27006e2a1849SPeter Brune ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 27016e2a1849SPeter Brune 27026e2a1849SPeter Brune /* copy the line search context over */ 27037601faf0SJed Brown ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); 27047601faf0SJed Brown ierr = SNESGetLineSearch(snes->pc,&pclinesearch);CHKERRQ(ierr); 27056b2b7091SBarry Smith ierr = SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx);CHKERRQ(ierr); 27066b2b7091SBarry Smith ierr = SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx);CHKERRQ(ierr); 27076b2b7091SBarry Smith ierr = SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx);CHKERRQ(ierr); 27086b2b7091SBarry Smith ierr = SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx);CHKERRQ(ierr); 27096e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr); 27106e2a1849SPeter Brune } 271132b97717SPeter Brune if (snes->mf) { 271232b97717SPeter Brune ierr = SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);CHKERRQ(ierr); 271332b97717SPeter Brune } 271432b97717SPeter Brune if (snes->ops->usercompute && !snes->user) { 271532b97717SPeter Brune ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 271632b97717SPeter Brune } 27176e2a1849SPeter Brune 271837ec4e1aSPeter Brune snes->jac_iter = 0; 271937ec4e1aSPeter Brune snes->pre_iter = 0; 272037ec4e1aSPeter Brune 2721410397dcSLisandro Dalcin if (snes->ops->setup) { 2722410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2723410397dcSLisandro Dalcin } 272458c9b817SLisandro Dalcin 27256c67d002SPeter Brune if (snes->pc && (snes->pcside == PC_LEFT)) { 27266c67d002SPeter Brune if (snes->functype == SNES_FUNCTION_PRECONDITIONED) { 272755d4788fSPeter Brune ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); 2728be95d8f1SBarry Smith ierr = SNESLineSearchSetFunction(linesearch,SNESComputeFunctionDefaultNPC);CHKERRQ(ierr); 27296c67d002SPeter Brune } 27306c67d002SPeter Brune } 27316c67d002SPeter Brune 27327aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 27333a40ed3dSBarry Smith PetscFunctionReturn(0); 27349b94acceSBarry Smith } 27359b94acceSBarry Smith 27364a2ae208SSatish Balay #undef __FUNCT__ 273737596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 273837596af1SLisandro Dalcin /*@ 273937596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 274037596af1SLisandro Dalcin 274137596af1SLisandro Dalcin Collective on SNES 274237596af1SLisandro Dalcin 274337596af1SLisandro Dalcin Input Parameter: 274437596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 274537596af1SLisandro Dalcin 2746d25893d9SBarry Smith Level: intermediate 2747d25893d9SBarry Smith 2748d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 274937596af1SLisandro Dalcin 275037596af1SLisandro Dalcin .keywords: SNES, destroy 275137596af1SLisandro Dalcin 275237596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 275337596af1SLisandro Dalcin @*/ 275437596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 275537596af1SLisandro Dalcin { 275637596af1SLisandro Dalcin PetscErrorCode ierr; 275737596af1SLisandro Dalcin 275837596af1SLisandro Dalcin PetscFunctionBegin; 275937596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2760d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2761d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 27620298fd71SBarry Smith snes->user = NULL; 2763d25893d9SBarry Smith } 27648a23116dSBarry Smith if (snes->pc) { 27658a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 27668a23116dSBarry Smith } 27678a23116dSBarry Smith 276837596af1SLisandro Dalcin if (snes->ops->reset) { 276937596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 277037596af1SLisandro Dalcin } 27719e764e56SPeter Brune if (snes->ksp) { 27729e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 27739e764e56SPeter Brune } 27749e764e56SPeter Brune 27759e764e56SPeter Brune if (snes->linesearch) { 2776f1c6b773SPeter Brune ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 27779e764e56SPeter Brune } 27789e764e56SPeter Brune 27796bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 27806bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 27816bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 27826bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 27836bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 27846bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2785c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2786c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 2787f5af7f23SKarl Rupp 278837596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 278937596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 279037596af1SLisandro Dalcin PetscFunctionReturn(0); 279137596af1SLisandro Dalcin } 279237596af1SLisandro Dalcin 279337596af1SLisandro Dalcin #undef __FUNCT__ 27944a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 279552baeb72SSatish Balay /*@ 27969b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 27979b94acceSBarry Smith with SNESCreate(). 27989b94acceSBarry Smith 2799c7afd0dbSLois Curfman McInnes Collective on SNES 2800c7afd0dbSLois Curfman McInnes 28019b94acceSBarry Smith Input Parameter: 28029b94acceSBarry Smith . snes - the SNES context 28039b94acceSBarry Smith 280436851e7fSLois Curfman McInnes Level: beginner 280536851e7fSLois Curfman McInnes 28069b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 28079b94acceSBarry Smith 280863a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 28099b94acceSBarry Smith @*/ 28106bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 28119b94acceSBarry Smith { 28126849ba73SBarry Smith PetscErrorCode ierr; 28133a40ed3dSBarry Smith 28143a40ed3dSBarry Smith PetscFunctionBegin; 28156bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 28166bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 28176bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2818d4bb536fSBarry Smith 28196bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 28208a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 28216b8b9a38SLisandro Dalcin 2822e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 2823e04113cfSBarry Smith ierr = PetscObjectSAWsViewOff((PetscObject)*snes);CHKERRQ(ierr); 28246bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 28256d4c513bSLisandro Dalcin 28266bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 28276bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 2828f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 28296b8b9a38SLisandro Dalcin 28306bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 28316bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 28326bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 28336b8b9a38SLisandro Dalcin } 28346bf464f9SBarry Smith if ((*snes)->conv_malloc) { 28356bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 28366bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 283758c9b817SLisandro Dalcin } 28386bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2839a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 28403a40ed3dSBarry Smith PetscFunctionReturn(0); 28419b94acceSBarry Smith } 28429b94acceSBarry Smith 28439b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 28449b94acceSBarry Smith 28454a2ae208SSatish Balay #undef __FUNCT__ 2846a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2847a8054027SBarry Smith /*@ 2848a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2849a8054027SBarry Smith 28503f9fe445SBarry Smith Logically Collective on SNES 2851a8054027SBarry Smith 2852a8054027SBarry Smith Input Parameters: 2853a8054027SBarry Smith + snes - the SNES context 2854a8054027SBarry 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 28553b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2856a8054027SBarry Smith 2857a8054027SBarry Smith Options Database Keys: 2858a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2859a8054027SBarry Smith 2860a8054027SBarry Smith Notes: 2861a8054027SBarry Smith The default is 1 2862a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2863a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2864a8054027SBarry Smith 2865a8054027SBarry Smith Level: intermediate 2866a8054027SBarry Smith 2867a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2868a8054027SBarry Smith 2869e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2870a8054027SBarry Smith 2871a8054027SBarry Smith @*/ 28727087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2873a8054027SBarry Smith { 2874a8054027SBarry Smith PetscFunctionBegin; 28750700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2876e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2877e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2878c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2879a8054027SBarry Smith snes->lagpreconditioner = lag; 2880a8054027SBarry Smith PetscFunctionReturn(0); 2881a8054027SBarry Smith } 2882a8054027SBarry Smith 2883a8054027SBarry Smith #undef __FUNCT__ 2884efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2885efd51863SBarry Smith /*@ 2886efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2887efd51863SBarry Smith 2888efd51863SBarry Smith Logically Collective on SNES 2889efd51863SBarry Smith 2890efd51863SBarry Smith Input Parameters: 2891efd51863SBarry Smith + snes - the SNES context 2892efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2893efd51863SBarry Smith 2894efd51863SBarry Smith Options Database Keys: 2895efd51863SBarry Smith . -snes_grid_sequence <steps> 2896efd51863SBarry Smith 2897efd51863SBarry Smith Level: intermediate 2898efd51863SBarry Smith 2899c0df2a02SJed Brown Notes: 2900c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2901c0df2a02SJed Brown 2902efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2903efd51863SBarry Smith 2904fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetGridSequence() 2905efd51863SBarry Smith 2906efd51863SBarry Smith @*/ 2907efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2908efd51863SBarry Smith { 2909efd51863SBarry Smith PetscFunctionBegin; 2910efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2911efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2912efd51863SBarry Smith snes->gridsequence = steps; 2913efd51863SBarry Smith PetscFunctionReturn(0); 2914efd51863SBarry Smith } 2915efd51863SBarry Smith 2916efd51863SBarry Smith #undef __FUNCT__ 2917fa19ca70SBarry Smith #define __FUNCT__ "SNESGetGridSequence" 2918fa19ca70SBarry Smith /*@ 2919fa19ca70SBarry Smith SNESGetGridSequence - gets the number of steps of grid sequencing that SNES does 2920fa19ca70SBarry Smith 2921fa19ca70SBarry Smith Logically Collective on SNES 2922fa19ca70SBarry Smith 2923fa19ca70SBarry Smith Input Parameter: 2924fa19ca70SBarry Smith . snes - the SNES context 2925fa19ca70SBarry Smith 2926fa19ca70SBarry Smith Output Parameter: 2927fa19ca70SBarry Smith . steps - the number of refinements to do, defaults to 0 2928fa19ca70SBarry Smith 2929fa19ca70SBarry Smith Options Database Keys: 2930fa19ca70SBarry Smith . -snes_grid_sequence <steps> 2931fa19ca70SBarry Smith 2932fa19ca70SBarry Smith Level: intermediate 2933fa19ca70SBarry Smith 2934fa19ca70SBarry Smith Notes: 2935fa19ca70SBarry Smith Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2936fa19ca70SBarry Smith 2937fa19ca70SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2938fa19ca70SBarry Smith 2939fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetGridSequence() 2940fa19ca70SBarry Smith 2941fa19ca70SBarry Smith @*/ 2942fa19ca70SBarry Smith PetscErrorCode SNESGetGridSequence(SNES snes,PetscInt *steps) 2943fa19ca70SBarry Smith { 2944fa19ca70SBarry Smith PetscFunctionBegin; 2945fa19ca70SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2946fa19ca70SBarry Smith *steps = snes->gridsequence; 2947fa19ca70SBarry Smith PetscFunctionReturn(0); 2948fa19ca70SBarry Smith } 2949fa19ca70SBarry Smith 2950fa19ca70SBarry Smith #undef __FUNCT__ 2951a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2952a8054027SBarry Smith /*@ 2953a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2954a8054027SBarry Smith 29553f9fe445SBarry Smith Not Collective 2956a8054027SBarry Smith 2957a8054027SBarry Smith Input Parameter: 2958a8054027SBarry Smith . snes - the SNES context 2959a8054027SBarry Smith 2960a8054027SBarry Smith Output Parameter: 2961a8054027SBarry 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 29623b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2963a8054027SBarry Smith 2964a8054027SBarry Smith Options Database Keys: 2965a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2966a8054027SBarry Smith 2967a8054027SBarry Smith Notes: 2968a8054027SBarry Smith The default is 1 2969a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2970a8054027SBarry Smith 2971a8054027SBarry Smith Level: intermediate 2972a8054027SBarry Smith 2973a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2974a8054027SBarry Smith 2975a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2976a8054027SBarry Smith 2977a8054027SBarry Smith @*/ 29787087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2979a8054027SBarry Smith { 2980a8054027SBarry Smith PetscFunctionBegin; 29810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2982a8054027SBarry Smith *lag = snes->lagpreconditioner; 2983a8054027SBarry Smith PetscFunctionReturn(0); 2984a8054027SBarry Smith } 2985a8054027SBarry Smith 2986a8054027SBarry Smith #undef __FUNCT__ 2987e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2988e35cf81dSBarry Smith /*@ 2989e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2990e35cf81dSBarry Smith often the preconditioner is rebuilt. 2991e35cf81dSBarry Smith 29923f9fe445SBarry Smith Logically Collective on SNES 2993e35cf81dSBarry Smith 2994e35cf81dSBarry Smith Input Parameters: 2995e35cf81dSBarry Smith + snes - the SNES context 2996e35cf81dSBarry 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 2997fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2998e35cf81dSBarry Smith 2999e35cf81dSBarry Smith Options Database Keys: 3000e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 3001e35cf81dSBarry Smith 3002e35cf81dSBarry Smith Notes: 3003e35cf81dSBarry Smith The default is 1 3004e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3005fe3ffe1eSBarry 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 3006fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 3007e35cf81dSBarry Smith 3008e35cf81dSBarry Smith Level: intermediate 3009e35cf81dSBarry Smith 3010e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 3011e35cf81dSBarry Smith 3012e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 3013e35cf81dSBarry Smith 3014e35cf81dSBarry Smith @*/ 30157087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 3016e35cf81dSBarry Smith { 3017e35cf81dSBarry Smith PetscFunctionBegin; 30180700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3019e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 3020e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 3021c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 3022e35cf81dSBarry Smith snes->lagjacobian = lag; 3023e35cf81dSBarry Smith PetscFunctionReturn(0); 3024e35cf81dSBarry Smith } 3025e35cf81dSBarry Smith 3026e35cf81dSBarry Smith #undef __FUNCT__ 3027e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 3028e35cf81dSBarry Smith /*@ 3029e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 3030e35cf81dSBarry Smith 30313f9fe445SBarry Smith Not Collective 3032e35cf81dSBarry Smith 3033e35cf81dSBarry Smith Input Parameter: 3034e35cf81dSBarry Smith . snes - the SNES context 3035e35cf81dSBarry Smith 3036e35cf81dSBarry Smith Output Parameter: 3037e35cf81dSBarry 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 3038e35cf81dSBarry Smith the Jacobian is built etc. 3039e35cf81dSBarry Smith 3040e35cf81dSBarry Smith Options Database Keys: 3041e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 3042e35cf81dSBarry Smith 3043e35cf81dSBarry Smith Notes: 3044e35cf81dSBarry Smith The default is 1 3045e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3046e35cf81dSBarry Smith 3047e35cf81dSBarry Smith Level: intermediate 3048e35cf81dSBarry Smith 3049e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 3050e35cf81dSBarry Smith 3051e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 3052e35cf81dSBarry Smith 3053e35cf81dSBarry Smith @*/ 30547087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 3055e35cf81dSBarry Smith { 3056e35cf81dSBarry Smith PetscFunctionBegin; 30570700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3058e35cf81dSBarry Smith *lag = snes->lagjacobian; 3059e35cf81dSBarry Smith PetscFunctionReturn(0); 3060e35cf81dSBarry Smith } 3061e35cf81dSBarry Smith 3062e35cf81dSBarry Smith #undef __FUNCT__ 306337ec4e1aSPeter Brune #define __FUNCT__ "SNESSetLagJacobianPersists" 306437ec4e1aSPeter Brune /*@ 306537ec4e1aSPeter Brune SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves 306637ec4e1aSPeter Brune 306737ec4e1aSPeter Brune Logically collective on SNES 306837ec4e1aSPeter Brune 306937ec4e1aSPeter Brune Input Parameter: 307037ec4e1aSPeter Brune + snes - the SNES context 30719d7e2deaSPeter Brune - flg - jacobian lagging persists if true 307237ec4e1aSPeter Brune 307337ec4e1aSPeter Brune Options Database Keys: 307437ec4e1aSPeter Brune . -snes_lag_jacobian_persists <flg> 307537ec4e1aSPeter Brune 307637ec4e1aSPeter Brune Notes: This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by 307737ec4e1aSPeter Brune several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several 307837ec4e1aSPeter Brune timesteps may present huge efficiency gains. 307937ec4e1aSPeter Brune 308037ec4e1aSPeter Brune Level: developer 308137ec4e1aSPeter Brune 3082be95d8f1SBarry Smith .keywords: SNES, nonlinear, lag 308337ec4e1aSPeter Brune 3084be95d8f1SBarry Smith .seealso: SNESSetLagPreconditionerPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC() 308537ec4e1aSPeter Brune 308637ec4e1aSPeter Brune @*/ 308737ec4e1aSPeter Brune PetscErrorCode SNESSetLagJacobianPersists(SNES snes,PetscBool flg) 308837ec4e1aSPeter Brune { 308937ec4e1aSPeter Brune PetscFunctionBegin; 309037ec4e1aSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 309137ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes,flg,2); 309237ec4e1aSPeter Brune snes->lagjac_persist = flg; 309337ec4e1aSPeter Brune PetscFunctionReturn(0); 309437ec4e1aSPeter Brune } 309537ec4e1aSPeter Brune 309637ec4e1aSPeter Brune #undef __FUNCT__ 309737ec4e1aSPeter Brune #define __FUNCT__ "SNESSetLagPreconditionerPersists" 309837ec4e1aSPeter Brune /*@ 309937ec4e1aSPeter Brune SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple solves 310037ec4e1aSPeter Brune 310137ec4e1aSPeter Brune Logically Collective on SNES 310237ec4e1aSPeter Brune 310337ec4e1aSPeter Brune Input Parameter: 310437ec4e1aSPeter Brune + snes - the SNES context 31059d7e2deaSPeter Brune - flg - preconditioner lagging persists if true 310637ec4e1aSPeter Brune 310737ec4e1aSPeter Brune Options Database Keys: 310837ec4e1aSPeter Brune . -snes_lag_jacobian_persists <flg> 310937ec4e1aSPeter Brune 311037ec4e1aSPeter Brune Notes: This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale 311137ec4e1aSPeter Brune by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over 311237ec4e1aSPeter Brune several timesteps may present huge efficiency gains. 311337ec4e1aSPeter Brune 311437ec4e1aSPeter Brune Level: developer 311537ec4e1aSPeter Brune 3116be95d8f1SBarry Smith .keywords: SNES, nonlinear, lag 311737ec4e1aSPeter Brune 3118be95d8f1SBarry Smith .seealso: SNESSetLagJacobianPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC() 311937ec4e1aSPeter Brune 312037ec4e1aSPeter Brune @*/ 312137ec4e1aSPeter Brune PetscErrorCode SNESSetLagPreconditionerPersists(SNES snes,PetscBool flg) 312237ec4e1aSPeter Brune { 312337ec4e1aSPeter Brune PetscFunctionBegin; 312437ec4e1aSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 312537ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes,flg,2); 312637ec4e1aSPeter Brune snes->lagpre_persist = flg; 312737ec4e1aSPeter Brune PetscFunctionReturn(0); 312837ec4e1aSPeter Brune } 312937ec4e1aSPeter Brune 313037ec4e1aSPeter Brune #undef __FUNCT__ 31314a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 31329b94acceSBarry Smith /*@ 3133d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 31349b94acceSBarry Smith 31353f9fe445SBarry Smith Logically Collective on SNES 3136c7afd0dbSLois Curfman McInnes 31379b94acceSBarry Smith Input Parameters: 3138c7afd0dbSLois Curfman McInnes + snes - the SNES context 313970441072SBarry Smith . abstol - absolute convergence tolerance 314033174efeSLois Curfman McInnes . rtol - relative convergence tolerance 31415358d0d4SBarry Smith . stol - convergence tolerance in terms of the norm of the change in the solution between steps, || delta x || < stol*|| x || 314233174efeSLois Curfman McInnes . maxit - maximum number of iterations 3143c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 3144fee21e36SBarry Smith 314533174efeSLois Curfman McInnes Options Database Keys: 314670441072SBarry Smith + -snes_atol <abstol> - Sets abstol 3147c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 3148c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 3149c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 3150c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 31519b94acceSBarry Smith 3152d7a720efSLois Curfman McInnes Notes: 31539b94acceSBarry Smith The default maximum number of iterations is 50. 31549b94acceSBarry Smith The default maximum number of function evaluations is 1000. 31559b94acceSBarry Smith 315636851e7fSLois Curfman McInnes Level: intermediate 315736851e7fSLois Curfman McInnes 315833174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 31599b94acceSBarry Smith 31602492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 31619b94acceSBarry Smith @*/ 31627087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 31639b94acceSBarry Smith { 31643a40ed3dSBarry Smith PetscFunctionBegin; 31650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3166c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 3167c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 3168c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 3169c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 3170c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 3171c5eb9154SBarry Smith 3172ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 317357622a8eSBarry Smith if (abstol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g must be non-negative",(double)abstol); 3174ab54825eSJed Brown snes->abstol = abstol; 3175ab54825eSJed Brown } 3176ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 317757622a8eSBarry 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); 3178ab54825eSJed Brown snes->rtol = rtol; 3179ab54825eSJed Brown } 3180ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 318157622a8eSBarry Smith if (stol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %g must be non-negative",(double)stol); 3182c60f73f4SPeter Brune snes->stol = stol; 3183ab54825eSJed Brown } 3184ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 3185ce94432eSBarry Smith if (maxit < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 3186ab54825eSJed Brown snes->max_its = maxit; 3187ab54825eSJed Brown } 3188ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 3189ce94432eSBarry Smith if (maxf < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 3190ab54825eSJed Brown snes->max_funcs = maxf; 3191ab54825eSJed Brown } 319288976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 31933a40ed3dSBarry Smith PetscFunctionReturn(0); 31949b94acceSBarry Smith } 31959b94acceSBarry Smith 31964a2ae208SSatish Balay #undef __FUNCT__ 31974a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 31989b94acceSBarry Smith /*@ 319933174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 320033174efeSLois Curfman McInnes 3201c7afd0dbSLois Curfman McInnes Not Collective 3202c7afd0dbSLois Curfman McInnes 320333174efeSLois Curfman McInnes Input Parameters: 3204c7afd0dbSLois Curfman McInnes + snes - the SNES context 320585385478SLisandro Dalcin . atol - absolute convergence tolerance 320633174efeSLois Curfman McInnes . rtol - relative convergence tolerance 320733174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 320833174efeSLois Curfman McInnes of the change in the solution between steps 320933174efeSLois Curfman McInnes . maxit - maximum number of iterations 3210c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 3211fee21e36SBarry Smith 321233174efeSLois Curfman McInnes Notes: 32130298fd71SBarry Smith The user can specify NULL for any parameter that is not needed. 321433174efeSLois Curfman McInnes 321536851e7fSLois Curfman McInnes Level: intermediate 321636851e7fSLois Curfman McInnes 321733174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 321833174efeSLois Curfman McInnes 321933174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 322033174efeSLois Curfman McInnes @*/ 32217087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 322233174efeSLois Curfman McInnes { 32233a40ed3dSBarry Smith PetscFunctionBegin; 32240700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 322585385478SLisandro Dalcin if (atol) *atol = snes->abstol; 322633174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 3227c60f73f4SPeter Brune if (stol) *stol = snes->stol; 322833174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 322933174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 32303a40ed3dSBarry Smith PetscFunctionReturn(0); 323133174efeSLois Curfman McInnes } 323233174efeSLois Curfman McInnes 32334a2ae208SSatish Balay #undef __FUNCT__ 32344a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 323533174efeSLois Curfman McInnes /*@ 32369b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 32379b94acceSBarry Smith 32383f9fe445SBarry Smith Logically Collective on SNES 3239fee21e36SBarry Smith 3240c7afd0dbSLois Curfman McInnes Input Parameters: 3241c7afd0dbSLois Curfman McInnes + snes - the SNES context 3242c7afd0dbSLois Curfman McInnes - tol - tolerance 3243c7afd0dbSLois Curfman McInnes 32449b94acceSBarry Smith Options Database Key: 3245c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 32469b94acceSBarry Smith 324736851e7fSLois Curfman McInnes Level: intermediate 324836851e7fSLois Curfman McInnes 32499b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 32509b94acceSBarry Smith 32512492ecdbSBarry Smith .seealso: SNESSetTolerances() 32529b94acceSBarry Smith @*/ 32537087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 32549b94acceSBarry Smith { 32553a40ed3dSBarry Smith PetscFunctionBegin; 32560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3257c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 32589b94acceSBarry Smith snes->deltatol = tol; 32593a40ed3dSBarry Smith PetscFunctionReturn(0); 32609b94acceSBarry Smith } 32619b94acceSBarry Smith 3262df9fa365SBarry Smith /* 3263df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 3264df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 3265df9fa365SBarry Smith macros instead of functions 3266df9fa365SBarry Smith */ 32674a2ae208SSatish Balay #undef __FUNCT__ 32684619e776SBarry Smith #define __FUNCT__ "SNESMonitorLGResidualNorm" 3269d96771aaSLisandro Dalcin PetscErrorCode SNESMonitorLGResidualNorm(SNES snes,PetscInt it,PetscReal norm,void *ctx) 3270ce1608b8SBarry Smith { 3271dfbe8321SBarry Smith PetscErrorCode ierr; 3272ce1608b8SBarry Smith 3273ce1608b8SBarry Smith PetscFunctionBegin; 32740700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3275d96771aaSLisandro Dalcin ierr = KSPMonitorLGResidualNorm((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 3276ce1608b8SBarry Smith PetscFunctionReturn(0); 3277ce1608b8SBarry Smith } 3278ce1608b8SBarry Smith 32794a2ae208SSatish Balay #undef __FUNCT__ 3280a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 3281d96771aaSLisandro Dalcin PetscErrorCode SNESMonitorLGCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *lgctx) 3282df9fa365SBarry Smith { 3283dfbe8321SBarry Smith PetscErrorCode ierr; 3284df9fa365SBarry Smith 3285df9fa365SBarry Smith PetscFunctionBegin; 3286d96771aaSLisandro Dalcin ierr = KSPMonitorLGResidualNormCreate(comm,host,label,x,y,m,n,lgctx);CHKERRQ(ierr); 3287df9fa365SBarry Smith PetscFunctionReturn(0); 3288df9fa365SBarry Smith } 3289df9fa365SBarry Smith 32907087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 3291b271bb04SBarry Smith #undef __FUNCT__ 3292b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 32937087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 3294b271bb04SBarry Smith { 3295b271bb04SBarry Smith PetscDrawLG lg; 3296b271bb04SBarry Smith PetscErrorCode ierr; 3297b271bb04SBarry Smith PetscReal x,y,per; 3298b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 3299b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 3300b271bb04SBarry Smith PetscDraw draw; 3301b271bb04SBarry Smith 3302459f5d12SBarry Smith PetscFunctionBegin; 33034d4332d5SBarry Smith PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,4); 3304b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 3305b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3306b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3307b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 3308b271bb04SBarry Smith x = (PetscReal)n; 330977b4d14cSPeter Brune if (rnorm > 0.0) y = PetscLog10Real(rnorm); 331094c9c6d3SKarl Rupp else y = -15.0; 3311b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3312b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 3313b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 3314b271bb04SBarry Smith } 3315b271bb04SBarry Smith 3316b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 3317b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3318b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3319b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 3320b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 3321b271bb04SBarry Smith x = (PetscReal)n; 3322b271bb04SBarry Smith y = 100.0*per; 3323b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3324b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 3325b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 3326b271bb04SBarry Smith } 3327b271bb04SBarry Smith 3328b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 3329b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3330b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3331b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 3332b271bb04SBarry Smith x = (PetscReal)n; 3333b271bb04SBarry Smith y = (prev - rnorm)/prev; 3334b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3335b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 3336b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 3337b271bb04SBarry Smith } 3338b271bb04SBarry Smith 3339b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 3340b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3341b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3342b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 3343b271bb04SBarry Smith x = (PetscReal)n; 3344b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 3345b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 3346b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3347b271bb04SBarry Smith } 3348b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 3349b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 3350b271bb04SBarry Smith } 3351b271bb04SBarry Smith prev = rnorm; 3352b271bb04SBarry Smith PetscFunctionReturn(0); 3353b271bb04SBarry Smith } 3354b271bb04SBarry Smith 3355b271bb04SBarry Smith #undef __FUNCT__ 33567a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 3357228d79bcSJed Brown /*@ 3358228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 3359228d79bcSJed Brown 3360228d79bcSJed Brown Collective on SNES 3361228d79bcSJed Brown 3362228d79bcSJed Brown Input Parameters: 3363228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 3364228d79bcSJed Brown . iter - iteration number 3365228d79bcSJed Brown - rnorm - relative norm of the residual 3366228d79bcSJed Brown 3367228d79bcSJed Brown Notes: 3368228d79bcSJed Brown This routine is called by the SNES implementations. 3369228d79bcSJed Brown It does not typically need to be called by the user. 3370228d79bcSJed Brown 3371228d79bcSJed Brown Level: developer 3372228d79bcSJed Brown 3373228d79bcSJed Brown .seealso: SNESMonitorSet() 3374228d79bcSJed Brown @*/ 33757a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 33767a03ce2fSLisandro Dalcin { 33777a03ce2fSLisandro Dalcin PetscErrorCode ierr; 33787a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 33797a03ce2fSLisandro Dalcin 33807a03ce2fSLisandro Dalcin PetscFunctionBegin; 33815edff71fSBarry Smith ierr = VecLockPush(snes->vec_sol);CHKERRQ(ierr); 33827a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 33837a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 33847a03ce2fSLisandro Dalcin } 33855edff71fSBarry Smith ierr = VecLockPop(snes->vec_sol);CHKERRQ(ierr); 33867a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 33877a03ce2fSLisandro Dalcin } 33887a03ce2fSLisandro Dalcin 33899b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 33909b94acceSBarry Smith 3391bf388a1fSBarry Smith /*MC 3392bf388a1fSBarry Smith SNESMonitorFunction - functional form passed to SNESMonitorSet() to monitor convergence of nonlinear solver 3393bf388a1fSBarry Smith 3394bf388a1fSBarry Smith Synopsis: 3395aaa7dc30SBarry Smith #include <petscsnes.h> 3396bf388a1fSBarry Smith $ PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx) 3397bf388a1fSBarry Smith 3398bf388a1fSBarry Smith + snes - the SNES context 3399bf388a1fSBarry Smith . its - iteration number 3400bf388a1fSBarry Smith . norm - 2-norm function value (may be estimated) 3401bf388a1fSBarry Smith - mctx - [optional] monitoring context 3402bf388a1fSBarry Smith 3403878cb397SSatish Balay Level: advanced 3404878cb397SSatish Balay 3405bf388a1fSBarry Smith .seealso: SNESMonitorSet(), SNESMonitorGet() 3406bf388a1fSBarry Smith M*/ 3407bf388a1fSBarry Smith 34084a2ae208SSatish Balay #undef __FUNCT__ 3409a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 34109b94acceSBarry Smith /*@C 3411a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 34129b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 34139b94acceSBarry Smith progress. 34149b94acceSBarry Smith 34153f9fe445SBarry Smith Logically Collective on SNES 3416fee21e36SBarry Smith 3417c7afd0dbSLois Curfman McInnes Input Parameters: 3418c7afd0dbSLois Curfman McInnes + snes - the SNES context 34196e4dcb14SBarry Smith . f - the monitor function, see SNESMonitorFunction for the calling sequence 3420b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 34210298fd71SBarry Smith monitor routine (use NULL if no context is desired) 3422b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 34230298fd71SBarry Smith (may be NULL) 34249b94acceSBarry Smith 34259665c990SLois Curfman McInnes Options Database Keys: 3426a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 34274619e776SBarry Smith . -snes_monitor_lg_residualnorm - sets line graph monitor, 3428a6570f20SBarry Smith uses SNESMonitorLGCreate() 3429cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 3430c7afd0dbSLois Curfman McInnes been hardwired into a code by 3431a6570f20SBarry Smith calls to SNESMonitorSet(), but 3432c7afd0dbSLois Curfman McInnes does not cancel those set via 3433c7afd0dbSLois Curfman McInnes the options database. 34349665c990SLois Curfman McInnes 3435639f9d9dSBarry Smith Notes: 34366bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 3437a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 34386bc08f3fSLois Curfman McInnes order in which they were set. 3439639f9d9dSBarry Smith 3440025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 3441025f1a04SBarry Smith 344236851e7fSLois Curfman McInnes Level: intermediate 344336851e7fSLois Curfman McInnes 34449b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 34459b94acceSBarry Smith 3446bf388a1fSBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel(), SNESMonitorFunction 34479b94acceSBarry Smith @*/ 34486e4dcb14SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*f)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 34499b94acceSBarry Smith { 3450b90d0a6eSBarry Smith PetscInt i; 3451649052a6SBarry Smith PetscErrorCode ierr; 3452b90d0a6eSBarry Smith 34533a40ed3dSBarry Smith PetscFunctionBegin; 34540700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 345517186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 3456b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 34576e4dcb14SBarry Smith if (f == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 3458649052a6SBarry Smith if (monitordestroy) { 3459c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 3460649052a6SBarry Smith } 3461b90d0a6eSBarry Smith PetscFunctionReturn(0); 3462b90d0a6eSBarry Smith } 3463b90d0a6eSBarry Smith } 34646e4dcb14SBarry Smith snes->monitor[snes->numbermonitors] = f; 3465b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 3466639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 34673a40ed3dSBarry Smith PetscFunctionReturn(0); 34689b94acceSBarry Smith } 34699b94acceSBarry Smith 34704a2ae208SSatish Balay #undef __FUNCT__ 3471a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 3472a278d85bSSatish Balay /*@ 3473a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 34745cd90555SBarry Smith 34753f9fe445SBarry Smith Logically Collective on SNES 3476c7afd0dbSLois Curfman McInnes 34775cd90555SBarry Smith Input Parameters: 34785cd90555SBarry Smith . snes - the SNES context 34795cd90555SBarry Smith 34801a480d89SAdministrator Options Database Key: 3481a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 3482a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 3483c7afd0dbSLois Curfman McInnes set via the options database 34845cd90555SBarry Smith 34855cd90555SBarry Smith Notes: 34865cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 34875cd90555SBarry Smith 348836851e7fSLois Curfman McInnes Level: intermediate 348936851e7fSLois Curfman McInnes 34905cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 34915cd90555SBarry Smith 3492a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 34935cd90555SBarry Smith @*/ 34947087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 34955cd90555SBarry Smith { 3496d952e501SBarry Smith PetscErrorCode ierr; 3497d952e501SBarry Smith PetscInt i; 3498d952e501SBarry Smith 34995cd90555SBarry Smith PetscFunctionBegin; 35000700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3501d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 3502d952e501SBarry Smith if (snes->monitordestroy[i]) { 35033c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 3504d952e501SBarry Smith } 3505d952e501SBarry Smith } 35065cd90555SBarry Smith snes->numbermonitors = 0; 35075cd90555SBarry Smith PetscFunctionReturn(0); 35085cd90555SBarry Smith } 35095cd90555SBarry Smith 3510bf388a1fSBarry Smith /*MC 3511bf388a1fSBarry Smith SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver 3512bf388a1fSBarry Smith 3513bf388a1fSBarry Smith Synopsis: 3514aaa7dc30SBarry Smith #include <petscsnes.h> 3515bf388a1fSBarry Smith $ PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 3516bf388a1fSBarry Smith 3517bf388a1fSBarry Smith + snes - the SNES context 3518bf388a1fSBarry Smith . it - current iteration (0 is the first and is before any Newton step) 3519bf388a1fSBarry Smith . cctx - [optional] convergence context 3520bf388a1fSBarry Smith . reason - reason for convergence/divergence 3521bf388a1fSBarry Smith . xnorm - 2-norm of current iterate 3522bf388a1fSBarry Smith . gnorm - 2-norm of current step 3523bf388a1fSBarry Smith - f - 2-norm of function 3524bf388a1fSBarry Smith 3525878cb397SSatish Balay Level: intermediate 3526bf388a1fSBarry Smith 3527bf388a1fSBarry Smith .seealso: SNESSetConvergenceTest(), SNESGetConvergenceTest() 3528bf388a1fSBarry Smith M*/ 3529bf388a1fSBarry Smith 35304a2ae208SSatish Balay #undef __FUNCT__ 35314a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 35329b94acceSBarry Smith /*@C 35339b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 35349b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 35359b94acceSBarry Smith 35363f9fe445SBarry Smith Logically Collective on SNES 3537fee21e36SBarry Smith 3538c7afd0dbSLois Curfman McInnes Input Parameters: 3539c7afd0dbSLois Curfman McInnes + snes - the SNES context 3540bf388a1fSBarry Smith . SNESConvergenceTestFunction - routine to test for convergence 35410298fd71SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be NULL) 35420298fd71SBarry Smith - destroy - [optional] destructor for the context (may be NULL; NULL_FUNCTION in Fortran) 35439b94acceSBarry Smith 354436851e7fSLois Curfman McInnes Level: advanced 354536851e7fSLois Curfman McInnes 35469b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 35479b94acceSBarry Smith 3548e2a6519dSDmitry Karpeev .seealso: SNESConvergedDefault(), SNESConvergedSkip(), SNESConvergenceTestFunction 35499b94acceSBarry Smith @*/ 3550bf388a1fSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 35519b94acceSBarry Smith { 35527f7931b9SBarry Smith PetscErrorCode ierr; 35537f7931b9SBarry Smith 35543a40ed3dSBarry Smith PetscFunctionBegin; 35550700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3556e2a6519dSDmitry Karpeev if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip; 35577f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 35587f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 35597f7931b9SBarry Smith } 3560bf388a1fSBarry Smith snes->ops->converged = SNESConvergenceTestFunction; 35617f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 356285385478SLisandro Dalcin snes->cnvP = cctx; 35633a40ed3dSBarry Smith PetscFunctionReturn(0); 35649b94acceSBarry Smith } 35659b94acceSBarry Smith 35664a2ae208SSatish Balay #undef __FUNCT__ 35674a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 356852baeb72SSatish Balay /*@ 3569184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 3570184914b5SBarry Smith 3571184914b5SBarry Smith Not Collective 3572184914b5SBarry Smith 3573184914b5SBarry Smith Input Parameter: 3574184914b5SBarry Smith . snes - the SNES context 3575184914b5SBarry Smith 3576184914b5SBarry Smith Output Parameter: 35774d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 3578184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 3579184914b5SBarry Smith 3580184914b5SBarry Smith Level: intermediate 3581184914b5SBarry Smith 3582184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 3583184914b5SBarry Smith 3584184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 3585184914b5SBarry Smith 358633866048SMatthew G. Knepley .seealso: SNESSetConvergenceTest(), SNESSetConvergedReason(), SNESConvergedReason 3587184914b5SBarry Smith @*/ 35887087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 3589184914b5SBarry Smith { 3590184914b5SBarry Smith PetscFunctionBegin; 35910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35924482741eSBarry Smith PetscValidPointer(reason,2); 3593184914b5SBarry Smith *reason = snes->reason; 3594184914b5SBarry Smith PetscFunctionReturn(0); 3595184914b5SBarry Smith } 3596184914b5SBarry Smith 35974a2ae208SSatish Balay #undef __FUNCT__ 359833866048SMatthew G. Knepley #define __FUNCT__ "SNESSetConvergedReason" 359933866048SMatthew G. Knepley /*@ 360033866048SMatthew G. Knepley SNESSetConvergedReason - Sets the reason the SNES iteration was stopped. 360133866048SMatthew G. Knepley 360233866048SMatthew G. Knepley Not Collective 360333866048SMatthew G. Knepley 360433866048SMatthew G. Knepley Input Parameters: 360533866048SMatthew G. Knepley + snes - the SNES context 360633866048SMatthew G. Knepley - reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 360733866048SMatthew G. Knepley manual pages for the individual convergence tests for complete lists 360833866048SMatthew G. Knepley 360933866048SMatthew G. Knepley Level: intermediate 361033866048SMatthew G. Knepley 361133866048SMatthew G. Knepley .keywords: SNES, nonlinear, set, convergence, test 361233866048SMatthew G. Knepley .seealso: SNESGetConvergedReason(), SNESSetConvergenceTest(), SNESConvergedReason 361333866048SMatthew G. Knepley @*/ 361433866048SMatthew G. Knepley PetscErrorCode SNESSetConvergedReason(SNES snes,SNESConvergedReason reason) 361533866048SMatthew G. Knepley { 361633866048SMatthew G. Knepley PetscFunctionBegin; 361733866048SMatthew G. Knepley PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 361833866048SMatthew G. Knepley snes->reason = reason; 361933866048SMatthew G. Knepley PetscFunctionReturn(0); 362033866048SMatthew G. Knepley } 362133866048SMatthew G. Knepley 362233866048SMatthew G. Knepley #undef __FUNCT__ 36234a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 3624c9005455SLois Curfman McInnes /*@ 3625c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 3626c9005455SLois Curfman McInnes 36273f9fe445SBarry Smith Logically Collective on SNES 3628fee21e36SBarry Smith 3629c7afd0dbSLois Curfman McInnes Input Parameters: 3630c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 36318c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 3632cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 3633758f92a0SBarry Smith . na - size of a and its 363464731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 3635758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 3636c7afd0dbSLois Curfman McInnes 3637308dcc3eSBarry Smith Notes: 36380298fd71SBarry Smith If 'a' and 'its' are NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 3639308dcc3eSBarry Smith default array of length 10000 is allocated. 3640308dcc3eSBarry Smith 3641c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 3642c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 3643c9005455SLois Curfman McInnes during the section of code that is being timed. 3644c9005455SLois Curfman McInnes 364536851e7fSLois Curfman McInnes Level: intermediate 364636851e7fSLois Curfman McInnes 3647c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 3648758f92a0SBarry Smith 364908405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 3650758f92a0SBarry Smith 3651c9005455SLois Curfman McInnes @*/ 36527087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 3653c9005455SLois Curfman McInnes { 3654308dcc3eSBarry Smith PetscErrorCode ierr; 3655308dcc3eSBarry Smith 36563a40ed3dSBarry Smith PetscFunctionBegin; 36570700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36587a1ec6d4SBarry Smith if (a) PetscValidScalarPointer(a,2); 3659a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 36607a1ec6d4SBarry Smith if (!a) { 3661308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 36627fdeb8b9SBarry Smith ierr = PetscCalloc1(na,&a);CHKERRQ(ierr); 36637fdeb8b9SBarry Smith ierr = PetscCalloc1(na,&its);CHKERRQ(ierr); 3664f5af7f23SKarl Rupp 3665308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 3666308dcc3eSBarry Smith } 3667c9005455SLois Curfman McInnes snes->conv_hist = a; 3668758f92a0SBarry Smith snes->conv_hist_its = its; 3669758f92a0SBarry Smith snes->conv_hist_max = na; 3670a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 3671758f92a0SBarry Smith snes->conv_hist_reset = reset; 3672758f92a0SBarry Smith PetscFunctionReturn(0); 3673758f92a0SBarry Smith } 3674758f92a0SBarry Smith 3675308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3676c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 3677c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 367899e0435eSBarry Smith 3679308dcc3eSBarry Smith #undef __FUNCT__ 3680308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 36818cc058d9SJed Brown PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3682308dcc3eSBarry Smith { 3683308dcc3eSBarry Smith mxArray *mat; 3684308dcc3eSBarry Smith PetscInt i; 3685308dcc3eSBarry Smith PetscReal *ar; 3686308dcc3eSBarry Smith 3687308dcc3eSBarry Smith PetscFunctionBegin; 3688308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3689308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3690f5af7f23SKarl Rupp for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i]; 3691308dcc3eSBarry Smith PetscFunctionReturn(mat); 3692308dcc3eSBarry Smith } 3693308dcc3eSBarry Smith #endif 3694308dcc3eSBarry Smith 36954a2ae208SSatish Balay #undef __FUNCT__ 36964a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 36970c4c9dddSBarry Smith /*@C 3698758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3699758f92a0SBarry Smith 37003f9fe445SBarry Smith Not Collective 3701758f92a0SBarry Smith 3702758f92a0SBarry Smith Input Parameter: 3703758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3704758f92a0SBarry Smith 3705758f92a0SBarry Smith Output Parameters: 3706758f92a0SBarry Smith . a - array to hold history 3707758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3708758f92a0SBarry Smith negative if not converged) for each solve. 3709758f92a0SBarry Smith - na - size of a and its 3710758f92a0SBarry Smith 3711758f92a0SBarry Smith Notes: 3712758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3713758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3714758f92a0SBarry Smith 3715758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3716758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3717758f92a0SBarry Smith during the section of code that is being timed. 3718758f92a0SBarry Smith 3719758f92a0SBarry Smith Level: intermediate 3720758f92a0SBarry Smith 3721758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3722758f92a0SBarry Smith 3723758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3724758f92a0SBarry Smith 3725758f92a0SBarry Smith @*/ 37267087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3727758f92a0SBarry Smith { 3728758f92a0SBarry Smith PetscFunctionBegin; 37290700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3730758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3731758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3732758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 37333a40ed3dSBarry Smith PetscFunctionReturn(0); 3734c9005455SLois Curfman McInnes } 3735c9005455SLois Curfman McInnes 3736e74ef692SMatthew Knepley #undef __FUNCT__ 3737e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 3738ac226902SBarry Smith /*@C 373976b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3740eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 37417e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 374276b2cf59SMatthew Knepley 37433f9fe445SBarry Smith Logically Collective on SNES 374476b2cf59SMatthew Knepley 374576b2cf59SMatthew Knepley Input Parameters: 374676b2cf59SMatthew Knepley . snes - The nonlinear solver context 374776b2cf59SMatthew Knepley . func - The function 374876b2cf59SMatthew Knepley 374976b2cf59SMatthew Knepley Calling sequence of func: 3750b5d30489SBarry Smith . func (SNES snes, PetscInt step); 375176b2cf59SMatthew Knepley 375276b2cf59SMatthew Knepley . step - The current step of the iteration 375376b2cf59SMatthew Knepley 3754fe97e370SBarry Smith Level: advanced 3755fe97e370SBarry Smith 3756fe97e370SBarry 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() 3757fe97e370SBarry Smith This is not used by most users. 375876b2cf59SMatthew Knepley 375976b2cf59SMatthew Knepley .keywords: SNES, update 3760b5d30489SBarry Smith 37618d359177SBarry Smith .seealso SNESSetJacobian(), SNESSolve() 376276b2cf59SMatthew Knepley @*/ 37637087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 376476b2cf59SMatthew Knepley { 376576b2cf59SMatthew Knepley PetscFunctionBegin; 37660700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3767e7788613SBarry Smith snes->ops->update = func; 376876b2cf59SMatthew Knepley PetscFunctionReturn(0); 376976b2cf59SMatthew Knepley } 377076b2cf59SMatthew Knepley 3771e74ef692SMatthew Knepley #undef __FUNCT__ 37724a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 37739b94acceSBarry Smith /* 37749b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 37759b94acceSBarry Smith positive parameter delta. 37769b94acceSBarry Smith 37779b94acceSBarry Smith Input Parameters: 3778c7afd0dbSLois Curfman McInnes + snes - the SNES context 37799b94acceSBarry Smith . y - approximate solution of linear system 37809b94acceSBarry Smith . fnorm - 2-norm of current function 3781c7afd0dbSLois Curfman McInnes - delta - trust region size 37829b94acceSBarry Smith 37839b94acceSBarry Smith Output Parameters: 3784c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 37859b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 37869b94acceSBarry Smith region, and exceeds zero otherwise. 3787c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 37889b94acceSBarry Smith 37899b94acceSBarry Smith Note: 379004d7464bSBarry Smith For non-trust region methods such as SNESNEWTONLS, the parameter delta 37919b94acceSBarry Smith is set to be the maximum allowable step size. 37929b94acceSBarry Smith 37939b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 37949b94acceSBarry Smith */ 3795dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 37969b94acceSBarry Smith { 3797064f8208SBarry Smith PetscReal nrm; 3798ea709b57SSatish Balay PetscScalar cnorm; 3799dfbe8321SBarry Smith PetscErrorCode ierr; 38003a40ed3dSBarry Smith 38013a40ed3dSBarry Smith PetscFunctionBegin; 38020700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 38030700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3804c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3805184914b5SBarry Smith 3806064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3807064f8208SBarry Smith if (nrm > *delta) { 3808064f8208SBarry Smith nrm = *delta/nrm; 3809064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3810064f8208SBarry Smith cnorm = nrm; 38112dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 38129b94acceSBarry Smith *ynorm = *delta; 38139b94acceSBarry Smith } else { 38149b94acceSBarry Smith *gpnorm = 0.0; 3815064f8208SBarry Smith *ynorm = nrm; 38169b94acceSBarry Smith } 38173a40ed3dSBarry Smith PetscFunctionReturn(0); 38189b94acceSBarry Smith } 38199b94acceSBarry Smith 38204a2ae208SSatish Balay #undef __FUNCT__ 38212a359c20SBarry Smith #define __FUNCT__ "SNESReasonView" 38222a359c20SBarry Smith /*@ 38232a359c20SBarry Smith SNESReasonView - Displays the reason a SNES solve converged or diverged to a viewer 38242a359c20SBarry Smith 38252a359c20SBarry Smith Collective on SNES 38262a359c20SBarry Smith 38272a359c20SBarry Smith Parameter: 38282a359c20SBarry Smith + snes - iterative context obtained from SNESCreate() 38292a359c20SBarry Smith - viewer - the viewer to display the reason 38302a359c20SBarry Smith 38312a359c20SBarry Smith 38322a359c20SBarry Smith Options Database Keys: 38332a359c20SBarry Smith . -snes_converged_reason - print reason for converged or diverged, also prints number of iterations 38342a359c20SBarry Smith 38352a359c20SBarry Smith Level: beginner 38362a359c20SBarry Smith 38372a359c20SBarry Smith .keywords: SNES, solve, linear system 38382a359c20SBarry Smith 38392a359c20SBarry Smith .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault() 38402a359c20SBarry Smith 38412a359c20SBarry Smith @*/ 38422a359c20SBarry Smith PetscErrorCode SNESReasonView(SNES snes,PetscViewer viewer) 38432a359c20SBarry Smith { 38442a359c20SBarry Smith PetscErrorCode ierr; 38452a359c20SBarry Smith PetscBool isAscii; 38462a359c20SBarry Smith 38472a359c20SBarry Smith PetscFunctionBegin; 38482a359c20SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);CHKERRQ(ierr); 38492a359c20SBarry Smith if (isAscii) { 38502a359c20SBarry Smith ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 38512a359c20SBarry Smith if (snes->reason > 0) { 38522a359c20SBarry Smith if (((PetscObject) snes)->prefix) { 38532a359c20SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve converged due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 38542a359c20SBarry Smith } else { 38552a359c20SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 38562a359c20SBarry Smith } 38572a359c20SBarry Smith } else { 38582a359c20SBarry Smith if (((PetscObject) snes)->prefix) { 38592a359c20SBarry 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); 38602a359c20SBarry Smith } else { 38612a359c20SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 38622a359c20SBarry Smith } 38632a359c20SBarry Smith } 38642a359c20SBarry Smith ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 38652a359c20SBarry Smith } 38662a359c20SBarry Smith PetscFunctionReturn(0); 38672a359c20SBarry Smith } 38682a359c20SBarry Smith 38692a359c20SBarry Smith #undef __FUNCT__ 38702a359c20SBarry Smith #define __FUNCT__ "SNESReasonViewFromOptions" 38712a359c20SBarry Smith /*@C 38722a359c20SBarry Smith SNESReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed. 38732a359c20SBarry Smith 38742a359c20SBarry Smith Collective on SNES 38752a359c20SBarry Smith 38762a359c20SBarry Smith Input Parameters: 38772a359c20SBarry Smith . snes - the SNES object 38782a359c20SBarry Smith 38792a359c20SBarry Smith Level: intermediate 38802a359c20SBarry Smith 38812a359c20SBarry Smith @*/ 38822a359c20SBarry Smith PetscErrorCode SNESReasonViewFromOptions(SNES snes) 38832a359c20SBarry Smith { 38842a359c20SBarry Smith PetscErrorCode ierr; 38852a359c20SBarry Smith PetscViewer viewer; 38862a359c20SBarry Smith PetscBool flg; 38872a359c20SBarry Smith static PetscBool incall = PETSC_FALSE; 38882a359c20SBarry Smith PetscViewerFormat format; 38892a359c20SBarry Smith 38902a359c20SBarry Smith PetscFunctionBegin; 38912a359c20SBarry Smith if (incall) PetscFunctionReturn(0); 38922a359c20SBarry Smith incall = PETSC_TRUE; 38932a359c20SBarry Smith ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_converged_reason",&viewer,&format,&flg);CHKERRQ(ierr); 38942a359c20SBarry Smith if (flg) { 38952a359c20SBarry Smith ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 38962a359c20SBarry Smith ierr = SNESReasonView(snes,viewer);CHKERRQ(ierr); 38972a359c20SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 38982a359c20SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 38992a359c20SBarry Smith } 39002a359c20SBarry Smith incall = PETSC_FALSE; 39012a359c20SBarry Smith PetscFunctionReturn(0); 39022a359c20SBarry Smith } 39032a359c20SBarry Smith 39042a359c20SBarry Smith #undef __FUNCT__ 39054a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 39066ce558aeSBarry Smith /*@C 3907f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3908f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 39099b94acceSBarry Smith 3910c7afd0dbSLois Curfman McInnes Collective on SNES 3911c7afd0dbSLois Curfman McInnes 3912b2002411SLois Curfman McInnes Input Parameters: 3913c7afd0dbSLois Curfman McInnes + snes - the SNES context 39140298fd71SBarry Smith . b - the constant part of the equation F(x) = b, or NULL to use zero. 391585385478SLisandro Dalcin - x - the solution vector. 39169b94acceSBarry Smith 3917b2002411SLois Curfman McInnes Notes: 39188ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 39198ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 39208ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 39218ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 39228ddd3da0SLois Curfman McInnes 392336851e7fSLois Curfman McInnes Level: beginner 392436851e7fSLois Curfman McInnes 39259b94acceSBarry Smith .keywords: SNES, nonlinear, solve 39269b94acceSBarry Smith 3927c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 39289b94acceSBarry Smith @*/ 39297087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 39309b94acceSBarry Smith { 3931dfbe8321SBarry Smith PetscErrorCode ierr; 3932ace3abfcSBarry Smith PetscBool flg; 3933efd51863SBarry Smith PetscInt grid; 39340298fd71SBarry Smith Vec xcreated = NULL; 3935caa4e7f2SJed Brown DM dm; 3936052efed2SBarry Smith 39373a40ed3dSBarry Smith PetscFunctionBegin; 39380700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3939a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3940a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 39410700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 394285385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 394385385478SLisandro Dalcin 3944caa4e7f2SJed Brown if (!x) { 3945caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3946caa4e7f2SJed Brown ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 3947a69afd8bSBarry Smith x = xcreated; 3948a69afd8bSBarry Smith } 3949ce1779c8SBarry Smith ierr = SNESViewFromOptions(snes,NULL,"-snes_view_pre");CHKERRQ(ierr); 3950f05ece33SBarry Smith 3951ce94432eSBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);} 3952efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3953efd51863SBarry Smith 395485385478SLisandro Dalcin /* set solution vector */ 3955efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 39566bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 395785385478SLisandro Dalcin snes->vec_sol = x; 3958caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3959caa4e7f2SJed Brown 3960caa4e7f2SJed Brown /* set affine vector if provided */ 396185385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 39626bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 396385385478SLisandro Dalcin snes->vec_rhs = b; 396485385478SLisandro Dalcin 3965154060b5SMatthew G. Knepley if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 3966154060b5SMatthew 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"); 3967154060b5SMatthew G. Knepley if (!snes->vec_sol_update /* && snes->vec_sol */) { 3968154060b5SMatthew G. Knepley ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 3969154060b5SMatthew G. Knepley ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update);CHKERRQ(ierr); 3970154060b5SMatthew G. Knepley } 3971154060b5SMatthew G. Knepley ierr = DMShellSetGlobalVector(dm,snes->vec_sol);CHKERRQ(ierr); 397270e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 39733f149594SLisandro Dalcin 39747eee914bSBarry Smith if (!grid) { 39757eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3976d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3977d25893d9SBarry Smith } 3978dd568438SSatish Balay } 3979d25893d9SBarry Smith 3980abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 3981971e163fSPeter Brune if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;} 3982d5e45103SBarry Smith 39833f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 39844936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 398585385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 398617186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 3987422a814eSBarry Smith snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */ 39883f149594SLisandro Dalcin 398937ec4e1aSPeter Brune if (snes->lagjac_persist) snes->jac_iter += snes->iter; 399037ec4e1aSPeter Brune if (snes->lagpre_persist) snes->pre_iter += snes->iter; 399137ec4e1aSPeter Brune 399290d69ab7SBarry Smith flg = PETSC_FALSE; 39930298fd71SBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,NULL);CHKERRQ(ierr); 3994da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 39952a359c20SBarry Smith ierr = SNESReasonViewFromOptions(snes);CHKERRQ(ierr); 39965968eb51SBarry Smith 3997ce94432eSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 39989c8e83a9SBarry Smith if (snes->reason < 0) break; 3999efd51863SBarry Smith if (grid < snes->gridsequence) { 4000efd51863SBarry Smith DM fine; 4001efd51863SBarry Smith Vec xnew; 4002efd51863SBarry Smith Mat interp; 4003efd51863SBarry Smith 4004ce94432eSBarry Smith ierr = DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine);CHKERRQ(ierr); 4005ce94432eSBarry Smith if (!fine) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 40060298fd71SBarry Smith ierr = DMCreateInterpolation(snes->dm,fine,&interp,NULL);CHKERRQ(ierr); 4007efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 4008efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 4009c833c3b5SJed Brown ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr); 4010efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 4011efd51863SBarry Smith x = xnew; 4012efd51863SBarry Smith 4013efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 4014efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 4015efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 4016ce94432eSBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr); 4017efd51863SBarry Smith } 4018efd51863SBarry Smith } 4019ce1779c8SBarry Smith ierr = SNESViewFromOptions(snes,NULL,"-snes_view");CHKERRQ(ierr); 4020685405a1SBarry Smith ierr = VecViewFromOptions(snes->vec_sol,(PetscObject)snes,"-snes_view_solution");CHKERRQ(ierr); 40213f7e2da0SPeter Brune 4022a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 4023e04113cfSBarry Smith ierr = PetscObjectSAWsBlock((PetscObject)snes);CHKERRQ(ierr); 40243a40ed3dSBarry Smith PetscFunctionReturn(0); 40259b94acceSBarry Smith } 40269b94acceSBarry Smith 40279b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 40289b94acceSBarry Smith 40294a2ae208SSatish Balay #undef __FUNCT__ 40304a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 403182bf6240SBarry Smith /*@C 40324b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 40339b94acceSBarry Smith 4034fee21e36SBarry Smith Collective on SNES 4035fee21e36SBarry Smith 4036c7afd0dbSLois Curfman McInnes Input Parameters: 4037c7afd0dbSLois Curfman McInnes + snes - the SNES context 4038454a90a3SBarry Smith - type - a known method 4039c7afd0dbSLois Curfman McInnes 4040c7afd0dbSLois Curfman McInnes Options Database Key: 4041454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 404204d7464bSBarry Smith of available methods (for instance, newtonls or newtontr) 4043ae12b187SLois Curfman McInnes 40449b94acceSBarry Smith Notes: 4045e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 404604d7464bSBarry Smith + SNESNEWTONLS - Newton's method with line search 4047c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 404804d7464bSBarry Smith . SNESNEWTONTR - Newton's method with trust region 4049c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 40509b94acceSBarry Smith 4051ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 4052ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 4053ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 4054ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 4055ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 4056ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 4057ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 4058ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 4059ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 4060b0a32e0cSBarry Smith appropriate method. 406136851e7fSLois Curfman McInnes 40628f6c3df8SBarry Smith Developer Notes: SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates 40638f6c3df8SBarry Smith the constructor in that list and calls it to create the spexific object. 40648f6c3df8SBarry Smith 406536851e7fSLois Curfman McInnes Level: intermediate 4066a703fe33SLois Curfman McInnes 4067454a90a3SBarry Smith .keywords: SNES, set, type 4068435da068SBarry Smith 40698f6c3df8SBarry Smith .seealso: SNESType, SNESCreate(), SNESDestroy(), SNESGetType(), SNESSetFromOptions() 4070435da068SBarry Smith 40719b94acceSBarry Smith @*/ 407219fd82e9SBarry Smith PetscErrorCode SNESSetType(SNES snes,SNESType type) 40739b94acceSBarry Smith { 4074dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 4075ace3abfcSBarry Smith PetscBool match; 40763a40ed3dSBarry Smith 40773a40ed3dSBarry Smith PetscFunctionBegin; 40780700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 40794482741eSBarry Smith PetscValidCharPointer(type,2); 408082bf6240SBarry Smith 4081251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 40820f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 408392ff6ae8SBarry Smith 40841c9cd337SJed Brown ierr = PetscFunctionListFind(SNESList,type,&r);CHKERRQ(ierr); 4085e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 408675396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 4087b5c23020SJed Brown if (snes->ops->destroy) { 4088b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 40890298fd71SBarry Smith snes->ops->destroy = NULL; 4090b5c23020SJed Brown } 409175396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 409275396ef9SLisandro Dalcin snes->ops->setup = 0; 409375396ef9SLisandro Dalcin snes->ops->solve = 0; 409475396ef9SLisandro Dalcin snes->ops->view = 0; 409575396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 409675396ef9SLisandro Dalcin snes->ops->destroy = 0; 409775396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 409875396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 4099f5af7f23SKarl Rupp 4100454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 410103bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 41023a40ed3dSBarry Smith PetscFunctionReturn(0); 41039b94acceSBarry Smith } 41049b94acceSBarry Smith 41054a2ae208SSatish Balay #undef __FUNCT__ 41064a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 41079b94acceSBarry Smith /*@C 41089a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 41099b94acceSBarry Smith 4110c7afd0dbSLois Curfman McInnes Not Collective 4111c7afd0dbSLois Curfman McInnes 41129b94acceSBarry Smith Input Parameter: 41134b0e389bSBarry Smith . snes - nonlinear solver context 41149b94acceSBarry Smith 41159b94acceSBarry Smith Output Parameter: 41163a7fca6bSBarry Smith . type - SNES method (a character string) 41179b94acceSBarry Smith 411836851e7fSLois Curfman McInnes Level: intermediate 411936851e7fSLois Curfman McInnes 4120454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 41219b94acceSBarry Smith @*/ 412219fd82e9SBarry Smith PetscErrorCode SNESGetType(SNES snes,SNESType *type) 41239b94acceSBarry Smith { 41243a40ed3dSBarry Smith PetscFunctionBegin; 41250700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 41264482741eSBarry Smith PetscValidPointer(type,2); 41277adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 41283a40ed3dSBarry Smith PetscFunctionReturn(0); 41299b94acceSBarry Smith } 41309b94acceSBarry Smith 41314a2ae208SSatish Balay #undef __FUNCT__ 41323cd8a7caSMatthew G. Knepley #define __FUNCT__ "SNESSetSolution" 41333cd8a7caSMatthew G. Knepley /*@ 41343cd8a7caSMatthew G. Knepley SNESSetSolution - Sets the solution vector for use by the SNES routines. 41353cd8a7caSMatthew G. Knepley 41363cd8a7caSMatthew G. Knepley Logically Collective on SNES and Vec 41373cd8a7caSMatthew G. Knepley 41383cd8a7caSMatthew G. Knepley Input Parameters: 41393cd8a7caSMatthew G. Knepley + snes - the SNES context obtained from SNESCreate() 41403cd8a7caSMatthew G. Knepley - u - the solution vector 41413cd8a7caSMatthew G. Knepley 41423cd8a7caSMatthew G. Knepley Level: beginner 41433cd8a7caSMatthew G. Knepley 41443cd8a7caSMatthew G. Knepley .keywords: SNES, set, solution 41453cd8a7caSMatthew G. Knepley @*/ 41463cd8a7caSMatthew G. Knepley PetscErrorCode SNESSetSolution(SNES snes, Vec u) 41473cd8a7caSMatthew G. Knepley { 41483cd8a7caSMatthew G. Knepley DM dm; 41493cd8a7caSMatthew G. Knepley PetscErrorCode ierr; 41503cd8a7caSMatthew G. Knepley 41513cd8a7caSMatthew G. Knepley PetscFunctionBegin; 41523cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 41533cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 41543cd8a7caSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) u);CHKERRQ(ierr); 41553cd8a7caSMatthew G. Knepley ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 41563cd8a7caSMatthew G. Knepley 41573cd8a7caSMatthew G. Knepley snes->vec_sol = u; 41583cd8a7caSMatthew G. Knepley 41593cd8a7caSMatthew G. Knepley ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 41603cd8a7caSMatthew G. Knepley ierr = DMShellSetGlobalVector(dm, u);CHKERRQ(ierr); 41613cd8a7caSMatthew G. Knepley PetscFunctionReturn(0); 41623cd8a7caSMatthew G. Knepley } 41633cd8a7caSMatthew G. Knepley 41643cd8a7caSMatthew G. Knepley #undef __FUNCT__ 41654a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 416652baeb72SSatish Balay /*@ 41679b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 4168c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 41699b94acceSBarry Smith 4170c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 4171c7afd0dbSLois Curfman McInnes 41729b94acceSBarry Smith Input Parameter: 41739b94acceSBarry Smith . snes - the SNES context 41749b94acceSBarry Smith 41759b94acceSBarry Smith Output Parameter: 41769b94acceSBarry Smith . x - the solution 41779b94acceSBarry Smith 417870e92668SMatthew Knepley Level: intermediate 417936851e7fSLois Curfman McInnes 41809b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 41819b94acceSBarry Smith 418285385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 41839b94acceSBarry Smith @*/ 41847087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 41859b94acceSBarry Smith { 41863a40ed3dSBarry Smith PetscFunctionBegin; 41870700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 41884482741eSBarry Smith PetscValidPointer(x,2); 418985385478SLisandro Dalcin *x = snes->vec_sol; 419070e92668SMatthew Knepley PetscFunctionReturn(0); 419170e92668SMatthew Knepley } 419270e92668SMatthew Knepley 419370e92668SMatthew Knepley #undef __FUNCT__ 41944a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 419552baeb72SSatish Balay /*@ 41969b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 41979b94acceSBarry Smith stored. 41989b94acceSBarry Smith 4199c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 4200c7afd0dbSLois Curfman McInnes 42019b94acceSBarry Smith Input Parameter: 42029b94acceSBarry Smith . snes - the SNES context 42039b94acceSBarry Smith 42049b94acceSBarry Smith Output Parameter: 42059b94acceSBarry Smith . x - the solution update 42069b94acceSBarry Smith 420736851e7fSLois Curfman McInnes Level: advanced 420836851e7fSLois Curfman McInnes 42099b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 42109b94acceSBarry Smith 421185385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 42129b94acceSBarry Smith @*/ 42137087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 42149b94acceSBarry Smith { 42153a40ed3dSBarry Smith PetscFunctionBegin; 42160700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 42174482741eSBarry Smith PetscValidPointer(x,2); 421885385478SLisandro Dalcin *x = snes->vec_sol_update; 42193a40ed3dSBarry Smith PetscFunctionReturn(0); 42209b94acceSBarry Smith } 42219b94acceSBarry Smith 42224a2ae208SSatish Balay #undef __FUNCT__ 42234a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 42249b94acceSBarry Smith /*@C 42253638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 42269b94acceSBarry Smith 4227a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 4228c7afd0dbSLois Curfman McInnes 42299b94acceSBarry Smith Input Parameter: 42309b94acceSBarry Smith . snes - the SNES context 42319b94acceSBarry Smith 42329b94acceSBarry Smith Output Parameter: 42330298fd71SBarry Smith + r - the vector that is used to store residuals (or NULL if you don't want it) 4234f8b49ee9SBarry Smith . f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details 42350298fd71SBarry Smith - ctx - the function context (or NULL if you don't want it) 42369b94acceSBarry Smith 423736851e7fSLois Curfman McInnes Level: advanced 423836851e7fSLois Curfman McInnes 4239a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 42409b94acceSBarry Smith 4241bf388a1fSBarry Smith .seealso: SNESSetFunction(), SNESGetSolution(), SNESFunction 42429b94acceSBarry Smith @*/ 4243f8b49ee9SBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx) 42449b94acceSBarry Smith { 4245a63bb30eSJed Brown PetscErrorCode ierr; 42466cab3a1bSJed Brown DM dm; 4247a63bb30eSJed Brown 42483a40ed3dSBarry Smith PetscFunctionBegin; 42490700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4250a63bb30eSJed Brown if (r) { 4251a63bb30eSJed Brown if (!snes->vec_func) { 4252a63bb30eSJed Brown if (snes->vec_rhs) { 4253a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 4254a63bb30eSJed Brown } else if (snes->vec_sol) { 4255a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 4256a63bb30eSJed Brown } else if (snes->dm) { 4257a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 4258a63bb30eSJed Brown } 4259a63bb30eSJed Brown } 4260a63bb30eSJed Brown *r = snes->vec_func; 4261a63bb30eSJed Brown } 42626cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4263f8b49ee9SBarry Smith ierr = DMSNESGetFunction(dm,f,ctx);CHKERRQ(ierr); 42643a40ed3dSBarry Smith PetscFunctionReturn(0); 42659b94acceSBarry Smith } 42669b94acceSBarry Smith 4267c79ef259SPeter Brune /*@C 4268be95d8f1SBarry Smith SNESGetNGS - Returns the NGS function and context. 4269c79ef259SPeter Brune 4270c79ef259SPeter Brune Input Parameter: 4271c79ef259SPeter Brune . snes - the SNES context 4272c79ef259SPeter Brune 4273c79ef259SPeter Brune Output Parameter: 4274be95d8f1SBarry Smith + f - the function (or NULL) see SNESNGSFunction for details 42750298fd71SBarry Smith - ctx - the function context (or NULL) 4276c79ef259SPeter Brune 4277c79ef259SPeter Brune Level: advanced 4278c79ef259SPeter Brune 4279c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 4280c79ef259SPeter Brune 4281be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESGetFunction() 4282c79ef259SPeter Brune @*/ 4283c79ef259SPeter Brune 42844a2ae208SSatish Balay #undef __FUNCT__ 4285be95d8f1SBarry Smith #define __FUNCT__ "SNESGetNGS" 4286be95d8f1SBarry Smith PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx) 4287646217ecSPeter Brune { 42886cab3a1bSJed Brown PetscErrorCode ierr; 42896cab3a1bSJed Brown DM dm; 42906cab3a1bSJed Brown 4291646217ecSPeter Brune PetscFunctionBegin; 4292646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 42936cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4294be95d8f1SBarry Smith ierr = DMSNESGetNGS(dm,f,ctx);CHKERRQ(ierr); 4295646217ecSPeter Brune PetscFunctionReturn(0); 4296646217ecSPeter Brune } 4297646217ecSPeter Brune 42984a2ae208SSatish Balay #undef __FUNCT__ 42994a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 43003c7409f5SSatish Balay /*@C 43013c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 4302d850072dSLois Curfman McInnes SNES options in the database. 43033c7409f5SSatish Balay 43043f9fe445SBarry Smith Logically Collective on SNES 4305fee21e36SBarry Smith 4306c7afd0dbSLois Curfman McInnes Input Parameter: 4307c7afd0dbSLois Curfman McInnes + snes - the SNES context 4308c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 4309c7afd0dbSLois Curfman McInnes 4310d850072dSLois Curfman McInnes Notes: 4311a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 4312c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 4313d850072dSLois Curfman McInnes 431436851e7fSLois Curfman McInnes Level: advanced 431536851e7fSLois Curfman McInnes 43163c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 4317a86d99e1SLois Curfman McInnes 4318a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 43193c7409f5SSatish Balay @*/ 43207087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 43213c7409f5SSatish Balay { 4322dfbe8321SBarry Smith PetscErrorCode ierr; 43233c7409f5SSatish Balay 43243a40ed3dSBarry Smith PetscFunctionBegin; 43250700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4326639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 43271cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 432835f5d045SPeter Brune if (snes->linesearch) { 43297601faf0SJed Brown ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 433008b6c495SPeter Brune ierr = PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 433135f5d045SPeter Brune } 433235f5d045SPeter Brune ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 43333a40ed3dSBarry Smith PetscFunctionReturn(0); 43343c7409f5SSatish Balay } 43353c7409f5SSatish Balay 43364a2ae208SSatish Balay #undef __FUNCT__ 43374a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 43383c7409f5SSatish Balay /*@C 4339f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 4340d850072dSLois Curfman McInnes SNES options in the database. 43413c7409f5SSatish Balay 43423f9fe445SBarry Smith Logically Collective on SNES 4343fee21e36SBarry Smith 4344c7afd0dbSLois Curfman McInnes Input Parameters: 4345c7afd0dbSLois Curfman McInnes + snes - the SNES context 4346c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 4347c7afd0dbSLois Curfman McInnes 4348d850072dSLois Curfman McInnes Notes: 4349a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 4350c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 4351d850072dSLois Curfman McInnes 435236851e7fSLois Curfman McInnes Level: advanced 435336851e7fSLois Curfman McInnes 43543c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 4355a86d99e1SLois Curfman McInnes 4356a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 43573c7409f5SSatish Balay @*/ 43587087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 43593c7409f5SSatish Balay { 4360dfbe8321SBarry Smith PetscErrorCode ierr; 43613c7409f5SSatish Balay 43623a40ed3dSBarry Smith PetscFunctionBegin; 43630700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4364639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 43651cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 436635f5d045SPeter Brune if (snes->linesearch) { 43677601faf0SJed Brown ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 436808b6c495SPeter Brune ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 436935f5d045SPeter Brune } 437035f5d045SPeter Brune ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 43713a40ed3dSBarry Smith PetscFunctionReturn(0); 43723c7409f5SSatish Balay } 43733c7409f5SSatish Balay 43744a2ae208SSatish Balay #undef __FUNCT__ 43754a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 43769ab63eb5SSatish Balay /*@C 43773c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 43783c7409f5SSatish Balay SNES options in the database. 43793c7409f5SSatish Balay 4380c7afd0dbSLois Curfman McInnes Not Collective 4381c7afd0dbSLois Curfman McInnes 43823c7409f5SSatish Balay Input Parameter: 43833c7409f5SSatish Balay . snes - the SNES context 43843c7409f5SSatish Balay 43853c7409f5SSatish Balay Output Parameter: 43863c7409f5SSatish Balay . prefix - pointer to the prefix string used 43873c7409f5SSatish Balay 43884ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 43899ab63eb5SSatish Balay sufficient length to hold the prefix. 43909ab63eb5SSatish Balay 439136851e7fSLois Curfman McInnes Level: advanced 439236851e7fSLois Curfman McInnes 43933c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 4394a86d99e1SLois Curfman McInnes 4395a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 43963c7409f5SSatish Balay @*/ 43977087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 43983c7409f5SSatish Balay { 4399dfbe8321SBarry Smith PetscErrorCode ierr; 44003c7409f5SSatish Balay 44013a40ed3dSBarry Smith PetscFunctionBegin; 44020700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4403639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 44043a40ed3dSBarry Smith PetscFunctionReturn(0); 44053c7409f5SSatish Balay } 44063c7409f5SSatish Balay 4407b2002411SLois Curfman McInnes 44084a2ae208SSatish Balay #undef __FUNCT__ 44094a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 44103cea93caSBarry Smith /*@C 44111c84c290SBarry Smith SNESRegister - Adds a method to the nonlinear solver package. 44121c84c290SBarry Smith 44131c84c290SBarry Smith Not collective 44141c84c290SBarry Smith 44151c84c290SBarry Smith Input Parameters: 44161c84c290SBarry Smith + name_solver - name of a new user-defined solver 44171c84c290SBarry Smith - routine_create - routine to create method context 44181c84c290SBarry Smith 44191c84c290SBarry Smith Notes: 44201c84c290SBarry Smith SNESRegister() may be called multiple times to add several user-defined solvers. 44211c84c290SBarry Smith 44221c84c290SBarry Smith Sample usage: 44231c84c290SBarry Smith .vb 4424bdf89e91SBarry Smith SNESRegister("my_solver",MySolverCreate); 44251c84c290SBarry Smith .ve 44261c84c290SBarry Smith 44271c84c290SBarry Smith Then, your solver can be chosen with the procedural interface via 44281c84c290SBarry Smith $ SNESSetType(snes,"my_solver") 44291c84c290SBarry Smith or at runtime via the option 44301c84c290SBarry Smith $ -snes_type my_solver 44311c84c290SBarry Smith 44321c84c290SBarry Smith Level: advanced 44331c84c290SBarry Smith 44341c84c290SBarry Smith Note: If your function is not being put into a shared library then use SNESRegister() instead 44351c84c290SBarry Smith 44361c84c290SBarry Smith .keywords: SNES, nonlinear, register 44371c84c290SBarry Smith 44381c84c290SBarry Smith .seealso: SNESRegisterAll(), SNESRegisterDestroy() 44393cea93caSBarry Smith 44407f6c08e0SMatthew Knepley Level: advanced 44413cea93caSBarry Smith @*/ 4442bdf89e91SBarry Smith PetscErrorCode SNESRegister(const char sname[],PetscErrorCode (*function)(SNES)) 4443b2002411SLois Curfman McInnes { 4444dfbe8321SBarry Smith PetscErrorCode ierr; 4445b2002411SLois Curfman McInnes 4446b2002411SLois Curfman McInnes PetscFunctionBegin; 4447a240a19fSJed Brown ierr = PetscFunctionListAdd(&SNESList,sname,function);CHKERRQ(ierr); 4448b2002411SLois Curfman McInnes PetscFunctionReturn(0); 4449b2002411SLois Curfman McInnes } 4450da9b6338SBarry Smith 4451da9b6338SBarry Smith #undef __FUNCT__ 4452da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 44537087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 4454da9b6338SBarry Smith { 4455dfbe8321SBarry Smith PetscErrorCode ierr; 445677431f27SBarry Smith PetscInt N,i,j; 4457da9b6338SBarry Smith Vec u,uh,fh; 4458da9b6338SBarry Smith PetscScalar value; 4459da9b6338SBarry Smith PetscReal norm; 4460da9b6338SBarry Smith 4461da9b6338SBarry Smith PetscFunctionBegin; 4462da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 4463da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 4464da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 4465da9b6338SBarry Smith 4466da9b6338SBarry Smith /* currently only works for sequential */ 446722d28d08SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");CHKERRQ(ierr); 4468da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 4469da9b6338SBarry Smith for (i=0; i<N; i++) { 4470da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 447177431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 4472da9b6338SBarry Smith for (j=-10; j<11; j++) { 44738b49ba18SBarry Smith value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0); 4474da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 44753ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 4476da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 447777431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 4478da9b6338SBarry Smith value = -value; 4479da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 4480da9b6338SBarry Smith } 4481da9b6338SBarry Smith } 44826bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 44836bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 4484da9b6338SBarry Smith PetscFunctionReturn(0); 4485da9b6338SBarry Smith } 448671f87433Sdalcinl 448771f87433Sdalcinl #undef __FUNCT__ 4488fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 448971f87433Sdalcinl /*@ 4490fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 449171f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 449271f87433Sdalcinl Newton method. 449371f87433Sdalcinl 44943f9fe445SBarry Smith Logically Collective on SNES 449571f87433Sdalcinl 449671f87433Sdalcinl Input Parameters: 449771f87433Sdalcinl + snes - SNES context 449871f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 449971f87433Sdalcinl 450064ba62caSBarry Smith Options Database: 450164ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 450264ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 450364ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 450464ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 450564ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 450664ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 450764ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 450864ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 450964ba62caSBarry Smith 451071f87433Sdalcinl Notes: 451171f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 451271f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 451371f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 451471f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 451571f87433Sdalcinl solver. 451671f87433Sdalcinl 451771f87433Sdalcinl Level: advanced 451871f87433Sdalcinl 451971f87433Sdalcinl Reference: 452071f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 452171f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 452271f87433Sdalcinl 452371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 452471f87433Sdalcinl 4525fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 452671f87433Sdalcinl @*/ 45277087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 452871f87433Sdalcinl { 452971f87433Sdalcinl PetscFunctionBegin; 45300700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4531acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 453271f87433Sdalcinl snes->ksp_ewconv = flag; 453371f87433Sdalcinl PetscFunctionReturn(0); 453471f87433Sdalcinl } 453571f87433Sdalcinl 453671f87433Sdalcinl #undef __FUNCT__ 4537fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 453871f87433Sdalcinl /*@ 4539fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 454071f87433Sdalcinl for computing relative tolerance for linear solvers within an 454171f87433Sdalcinl inexact Newton method. 454271f87433Sdalcinl 454371f87433Sdalcinl Not Collective 454471f87433Sdalcinl 454571f87433Sdalcinl Input Parameter: 454671f87433Sdalcinl . snes - SNES context 454771f87433Sdalcinl 454871f87433Sdalcinl Output Parameter: 454971f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 455071f87433Sdalcinl 455171f87433Sdalcinl Notes: 455271f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 455371f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 455471f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 455571f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 455671f87433Sdalcinl solver. 455771f87433Sdalcinl 455871f87433Sdalcinl Level: advanced 455971f87433Sdalcinl 456071f87433Sdalcinl Reference: 456171f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 456271f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 456371f87433Sdalcinl 456471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 456571f87433Sdalcinl 4566fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 456771f87433Sdalcinl @*/ 45687087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 456971f87433Sdalcinl { 457071f87433Sdalcinl PetscFunctionBegin; 45710700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 457271f87433Sdalcinl PetscValidPointer(flag,2); 457371f87433Sdalcinl *flag = snes->ksp_ewconv; 457471f87433Sdalcinl PetscFunctionReturn(0); 457571f87433Sdalcinl } 457671f87433Sdalcinl 457771f87433Sdalcinl #undef __FUNCT__ 4578fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 457971f87433Sdalcinl /*@ 4580fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 458171f87433Sdalcinl convergence criteria for the linear solvers within an inexact 458271f87433Sdalcinl Newton method. 458371f87433Sdalcinl 45843f9fe445SBarry Smith Logically Collective on SNES 458571f87433Sdalcinl 458671f87433Sdalcinl Input Parameters: 458771f87433Sdalcinl + snes - SNES context 458871f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 458971f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 459071f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 459171f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 459271f87433Sdalcinl (0 <= gamma2 <= 1) 459371f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 459471f87433Sdalcinl . alpha2 - power for safeguard 459571f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 459671f87433Sdalcinl 459771f87433Sdalcinl Note: 459871f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 459971f87433Sdalcinl 460071f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 460171f87433Sdalcinl 460271f87433Sdalcinl Level: advanced 460371f87433Sdalcinl 460471f87433Sdalcinl Reference: 460571f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 460671f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 460771f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 460871f87433Sdalcinl 460971f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 461071f87433Sdalcinl 4611fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 461271f87433Sdalcinl @*/ 4613f5af7f23SKarl Rupp PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 461471f87433Sdalcinl { 4615fa9f3622SBarry Smith SNESKSPEW *kctx; 46165fd66863SKarl Rupp 461771f87433Sdalcinl PetscFunctionBegin; 46180700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4619fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4620e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 4621c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 4622c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 4623c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 4624c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 4625c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 4626c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 4627c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 462871f87433Sdalcinl 462971f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 463071f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 463171f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 463271f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 463371f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 463471f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 463571f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 463671f87433Sdalcinl 4637f23aa3ddSBarry 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); 463857622a8eSBarry 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); 463957622a8eSBarry 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); 464057622a8eSBarry 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); 464157622a8eSBarry 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); 464257622a8eSBarry 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); 464371f87433Sdalcinl PetscFunctionReturn(0); 464471f87433Sdalcinl } 464571f87433Sdalcinl 464671f87433Sdalcinl #undef __FUNCT__ 4647fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 464871f87433Sdalcinl /*@ 4649fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 465071f87433Sdalcinl convergence criteria for the linear solvers within an inexact 465171f87433Sdalcinl Newton method. 465271f87433Sdalcinl 465371f87433Sdalcinl Not Collective 465471f87433Sdalcinl 465571f87433Sdalcinl Input Parameters: 465671f87433Sdalcinl snes - SNES context 465771f87433Sdalcinl 465871f87433Sdalcinl Output Parameters: 465971f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 466071f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 466171f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 4662bf388a1fSBarry Smith . gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1) 466371f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 466471f87433Sdalcinl . alpha2 - power for safeguard 466571f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 466671f87433Sdalcinl 466771f87433Sdalcinl Level: advanced 466871f87433Sdalcinl 466971f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 467071f87433Sdalcinl 4671fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 467271f87433Sdalcinl @*/ 4673bf388a1fSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 467471f87433Sdalcinl { 4675fa9f3622SBarry Smith SNESKSPEW *kctx; 46765fd66863SKarl Rupp 467771f87433Sdalcinl PetscFunctionBegin; 46780700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4679fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4680e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 468171f87433Sdalcinl if (version) *version = kctx->version; 468271f87433Sdalcinl if (rtol_0) *rtol_0 = kctx->rtol_0; 468371f87433Sdalcinl if (rtol_max) *rtol_max = kctx->rtol_max; 468471f87433Sdalcinl if (gamma) *gamma = kctx->gamma; 468571f87433Sdalcinl if (alpha) *alpha = kctx->alpha; 468671f87433Sdalcinl if (alpha2) *alpha2 = kctx->alpha2; 468771f87433Sdalcinl if (threshold) *threshold = kctx->threshold; 468871f87433Sdalcinl PetscFunctionReturn(0); 468971f87433Sdalcinl } 469071f87433Sdalcinl 469171f87433Sdalcinl #undef __FUNCT__ 4692d5378b5fSDmitry Karpeev #define __FUNCT__ "KSPPreSolve_SNESEW" 4693d5378b5fSDmitry Karpeev PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 469471f87433Sdalcinl { 469571f87433Sdalcinl PetscErrorCode ierr; 4696fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 469771f87433Sdalcinl PetscReal rtol = PETSC_DEFAULT,stol; 469871f87433Sdalcinl 469971f87433Sdalcinl PetscFunctionBegin; 4700d4211eb9SBarry Smith if (!snes->ksp_ewconv) PetscFunctionReturn(0); 470130058271SDmitry Karpeev if (!snes->iter) { 470230058271SDmitry Karpeev rtol = kctx->rtol_0; /* first time in, so use the original user rtol */ 470330058271SDmitry Karpeev ierr = VecNorm(snes->vec_func,NORM_2,&kctx->norm_first);CHKERRQ(ierr); 470430058271SDmitry Karpeev } 4705f5af7f23SKarl Rupp else { 470671f87433Sdalcinl if (kctx->version == 1) { 470771f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 470871f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 470985ec1a3cSBarry Smith stol = PetscPowReal(kctx->rtol_last,kctx->alpha2); 471071f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 471171f87433Sdalcinl } else if (kctx->version == 2) { 471285ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 471385ec1a3cSBarry Smith stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha); 471471f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 471571f87433Sdalcinl } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */ 471685ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 471771f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 471885ec1a3cSBarry Smith stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha); 471971f87433Sdalcinl stol = PetscMax(rtol,stol); 472071f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 472171f87433Sdalcinl /* safeguard: avoid oversolving */ 472230058271SDmitry Karpeev stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm; 472371f87433Sdalcinl stol = PetscMax(rtol,stol); 472471f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 4725e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 472671f87433Sdalcinl } 472771f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 472871f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 472971f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 473057622a8eSBarry Smith ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol);CHKERRQ(ierr); 473171f87433Sdalcinl PetscFunctionReturn(0); 473271f87433Sdalcinl } 473371f87433Sdalcinl 473471f87433Sdalcinl #undef __FUNCT__ 4735d5378b5fSDmitry Karpeev #define __FUNCT__ "KSPPostSolve_SNESEW" 4736d5378b5fSDmitry Karpeev PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 473771f87433Sdalcinl { 473871f87433Sdalcinl PetscErrorCode ierr; 4739fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 474071f87433Sdalcinl PCSide pcside; 474171f87433Sdalcinl Vec lres; 474271f87433Sdalcinl 474371f87433Sdalcinl PetscFunctionBegin; 4744d4211eb9SBarry Smith if (!snes->ksp_ewconv) PetscFunctionReturn(0); 474571f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 474671dbe336SPeter Brune kctx->norm_last = snes->norm; 474771f87433Sdalcinl if (kctx->version == 1) { 47484f00ce20SMatthew G. Knepley PC pc; 47494f00ce20SMatthew G. Knepley PetscBool isNone; 47504f00ce20SMatthew G. Knepley 47514f00ce20SMatthew G. Knepley ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr); 47524f00ce20SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) pc, PCNONE, &isNone);CHKERRQ(ierr); 4753b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 47544f00ce20SMatthew G. Knepley if (pcside == PC_RIGHT || isNone) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 475571f87433Sdalcinl /* KSP residual is true linear residual */ 475671f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 475771f87433Sdalcinl } else { 475871f87433Sdalcinl /* KSP residual is preconditioned residual */ 475971f87433Sdalcinl /* compute true linear residual norm */ 476071f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 476171f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 476271f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 476371f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 47646bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 476571f87433Sdalcinl } 476671f87433Sdalcinl } 476771f87433Sdalcinl PetscFunctionReturn(0); 476871f87433Sdalcinl } 476971f87433Sdalcinl 477071f87433Sdalcinl #undef __FUNCT__ 4771d4211eb9SBarry Smith #define __FUNCT__ "SNESGetKSP" 4772d4211eb9SBarry Smith /*@ 4773d4211eb9SBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 4774d4211eb9SBarry Smith 4775d4211eb9SBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 4776d4211eb9SBarry Smith 4777d4211eb9SBarry Smith Input Parameter: 4778d4211eb9SBarry Smith . snes - the SNES context 4779d4211eb9SBarry Smith 4780d4211eb9SBarry Smith Output Parameter: 4781d4211eb9SBarry Smith . ksp - the KSP context 4782d4211eb9SBarry Smith 4783d4211eb9SBarry Smith Notes: 4784d4211eb9SBarry Smith The user can then directly manipulate the KSP context to set various 4785d4211eb9SBarry Smith options, etc. Likewise, the user can then extract and manipulate the 4786d4211eb9SBarry Smith PC contexts as well. 4787d4211eb9SBarry Smith 4788d4211eb9SBarry Smith Level: beginner 4789d4211eb9SBarry Smith 4790d4211eb9SBarry Smith .keywords: SNES, nonlinear, get, KSP, context 4791d4211eb9SBarry Smith 4792d4211eb9SBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 4793d4211eb9SBarry Smith @*/ 4794d4211eb9SBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 479571f87433Sdalcinl { 479671f87433Sdalcinl PetscErrorCode ierr; 479771f87433Sdalcinl 479871f87433Sdalcinl PetscFunctionBegin; 4799d4211eb9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4800d4211eb9SBarry Smith PetscValidPointer(ksp,2); 4801d4211eb9SBarry Smith 4802d4211eb9SBarry Smith if (!snes->ksp) { 4803a5c2985bSBarry Smith PetscBool monitor = PETSC_FALSE; 4804a5c2985bSBarry Smith 4805d4211eb9SBarry Smith ierr = KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp);CHKERRQ(ierr); 4806d4211eb9SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 48073bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp);CHKERRQ(ierr); 4808d4211eb9SBarry Smith 4809d5378b5fSDmitry Karpeev ierr = KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes);CHKERRQ(ierr); 4810d5378b5fSDmitry Karpeev ierr = KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes);CHKERRQ(ierr); 4811a5c2985bSBarry Smith 4812e5f7ee39SBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-ksp_monitor_snes",&monitor,NULL);CHKERRQ(ierr); 4813a5c2985bSBarry Smith if (monitor) { 4814a5c2985bSBarry Smith ierr = KSPMonitorSet(snes->ksp,KSPMonitorSNES,snes,NULL);CHKERRQ(ierr); 4815a5c2985bSBarry Smith } 4816e5f7ee39SBarry Smith monitor = PETSC_FALSE; 4817e5f7ee39SBarry Smith ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-ksp_monitor_snes_lg",&monitor,NULL);CHKERRQ(ierr); 4818e5f7ee39SBarry Smith if (monitor) { 4819e5f7ee39SBarry Smith PetscObject *objs; 48208b0b5a47SLisandro Dalcin ierr = KSPMonitorSNESLGResidualNormCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,600,600,&objs);CHKERRQ(ierr); 4821e5f7ee39SBarry Smith objs[0] = (PetscObject) snes; 4822e5f7ee39SBarry Smith ierr = KSPMonitorSet(snes->ksp,(PetscErrorCode (*)(KSP,PetscInt,PetscReal,void*))KSPMonitorSNESLGResidualNorm,objs,(PetscErrorCode (*)(void**))KSPMonitorSNESLGResidualNormDestroy);CHKERRQ(ierr); 4823e5f7ee39SBarry Smith } 4824d4211eb9SBarry Smith } 4825d4211eb9SBarry Smith *ksp = snes->ksp; 482671f87433Sdalcinl PetscFunctionReturn(0); 482771f87433Sdalcinl } 48286c699258SBarry Smith 4829d4211eb9SBarry Smith 4830af0996ceSBarry Smith #include <petsc/private/dmimpl.h> 48316c699258SBarry Smith #undef __FUNCT__ 48326c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 48336c699258SBarry Smith /*@ 48346c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 48356c699258SBarry Smith 48363f9fe445SBarry Smith Logically Collective on SNES 48376c699258SBarry Smith 48386c699258SBarry Smith Input Parameters: 48396c699258SBarry Smith + snes - the preconditioner context 48406c699258SBarry Smith - dm - the dm 48416c699258SBarry Smith 48426c699258SBarry Smith Level: intermediate 48436c699258SBarry Smith 48446c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 48456c699258SBarry Smith @*/ 48467087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 48476c699258SBarry Smith { 48486c699258SBarry Smith PetscErrorCode ierr; 4849345fed2cSBarry Smith KSP ksp; 4850942e3340SBarry Smith DMSNES sdm; 48516c699258SBarry Smith 48526c699258SBarry Smith PetscFunctionBegin; 48530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4854d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 4855942e3340SBarry Smith if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */ 4856b4615a05SBarry Smith if (snes->dm->dmsnes && snes->dmAuto && !dm->dmsnes) { 4857942e3340SBarry Smith ierr = DMCopyDMSNES(snes->dm,dm);CHKERRQ(ierr); 4858942e3340SBarry Smith ierr = DMGetDMSNES(snes->dm,&sdm);CHKERRQ(ierr); 4859f5af7f23SKarl Rupp if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */ 48606cab3a1bSJed Brown } 48616bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 48626cab3a1bSJed Brown } 48636c699258SBarry Smith snes->dm = dm; 4864116d1032SJed Brown snes->dmAuto = PETSC_FALSE; 4865f5af7f23SKarl Rupp 4866345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4867345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4868f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 48692c155ee1SBarry Smith if (snes->pc) { 48702c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 4871be95d8f1SBarry Smith ierr = SNESSetNPCSide(snes,snes->pcside);CHKERRQ(ierr); 48722c155ee1SBarry Smith } 48736c699258SBarry Smith PetscFunctionReturn(0); 48746c699258SBarry Smith } 48756c699258SBarry Smith 48766c699258SBarry Smith #undef __FUNCT__ 48776c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 48786c699258SBarry Smith /*@ 48796c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 48806c699258SBarry Smith 48813f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 48826c699258SBarry Smith 48836c699258SBarry Smith Input Parameter: 48846c699258SBarry Smith . snes - the preconditioner context 48856c699258SBarry Smith 48866c699258SBarry Smith Output Parameter: 48876c699258SBarry Smith . dm - the dm 48886c699258SBarry Smith 48896c699258SBarry Smith Level: intermediate 48906c699258SBarry Smith 48916c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 48926c699258SBarry Smith @*/ 48937087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 48946c699258SBarry Smith { 48956cab3a1bSJed Brown PetscErrorCode ierr; 48966cab3a1bSJed Brown 48976c699258SBarry Smith PetscFunctionBegin; 48980700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 48996cab3a1bSJed Brown if (!snes->dm) { 4900ce94432eSBarry Smith ierr = DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm);CHKERRQ(ierr); 4901116d1032SJed Brown snes->dmAuto = PETSC_TRUE; 49026cab3a1bSJed Brown } 49036c699258SBarry Smith *dm = snes->dm; 49046c699258SBarry Smith PetscFunctionReturn(0); 49056c699258SBarry Smith } 49060807856dSBarry Smith 490731823bd8SMatthew G Knepley #undef __FUNCT__ 4908be95d8f1SBarry Smith #define __FUNCT__ "SNESSetNPC" 490931823bd8SMatthew G Knepley /*@ 4910be95d8f1SBarry Smith SNESSetNPC - Sets the nonlinear preconditioner to be used. 491131823bd8SMatthew G Knepley 491231823bd8SMatthew G Knepley Collective on SNES 491331823bd8SMatthew G Knepley 491431823bd8SMatthew G Knepley Input Parameters: 491531823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 491631823bd8SMatthew G Knepley - pc - the preconditioner object 491731823bd8SMatthew G Knepley 491831823bd8SMatthew G Knepley Notes: 4919be95d8f1SBarry Smith Use SNESGetNPC() to retrieve the preconditioner context (for example, 492031823bd8SMatthew G Knepley to configure it using the API). 492131823bd8SMatthew G Knepley 492231823bd8SMatthew G Knepley Level: developer 492331823bd8SMatthew G Knepley 492431823bd8SMatthew G Knepley .keywords: SNES, set, precondition 49253ad1a0b9SPatrick Farrell .seealso: SNESGetNPC(), SNESHasNPC() 492631823bd8SMatthew G Knepley @*/ 4927be95d8f1SBarry Smith PetscErrorCode SNESSetNPC(SNES snes, SNES pc) 492831823bd8SMatthew G Knepley { 492931823bd8SMatthew G Knepley PetscErrorCode ierr; 493031823bd8SMatthew G Knepley 493131823bd8SMatthew G Knepley PetscFunctionBegin; 493231823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 493331823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 493431823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 493531823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4936bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 493731823bd8SMatthew G Knepley snes->pc = pc; 49383bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->pc);CHKERRQ(ierr); 493931823bd8SMatthew G Knepley PetscFunctionReturn(0); 494031823bd8SMatthew G Knepley } 494131823bd8SMatthew G Knepley 494231823bd8SMatthew G Knepley #undef __FUNCT__ 4943be95d8f1SBarry Smith #define __FUNCT__ "SNESGetNPC" 494431823bd8SMatthew G Knepley /*@ 4945be95d8f1SBarry Smith SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver. 494631823bd8SMatthew G Knepley 494731823bd8SMatthew G Knepley Not Collective 494831823bd8SMatthew G Knepley 494931823bd8SMatthew G Knepley Input Parameter: 495031823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 495131823bd8SMatthew G Knepley 495231823bd8SMatthew G Knepley Output Parameter: 495331823bd8SMatthew G Knepley . pc - preconditioner context 495431823bd8SMatthew G Knepley 4955be95d8f1SBarry Smith Notes: If a SNES was previously set with SNESSetNPC() then that SNES is returned. 4956be95d8f1SBarry Smith 495731823bd8SMatthew G Knepley Level: developer 495831823bd8SMatthew G Knepley 495931823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 49603ad1a0b9SPatrick Farrell .seealso: SNESSetNPC(), SNESHasNPC() 496131823bd8SMatthew G Knepley @*/ 4962be95d8f1SBarry Smith PetscErrorCode SNESGetNPC(SNES snes, SNES *pc) 496331823bd8SMatthew G Knepley { 496431823bd8SMatthew G Knepley PetscErrorCode ierr; 4965a64e098fSPeter Brune const char *optionsprefix; 496631823bd8SMatthew G Knepley 496731823bd8SMatthew G Knepley PetscFunctionBegin; 496831823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 496931823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 497031823bd8SMatthew G Knepley if (!snes->pc) { 497182f516ccSBarry Smith ierr = SNESCreate(PetscObjectComm((PetscObject)snes),&snes->pc);CHKERRQ(ierr); 49724a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr); 49733bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr); 4974a64e098fSPeter Brune ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr); 4975a64e098fSPeter Brune ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr); 4976a64e098fSPeter Brune ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr); 4977971e163fSPeter Brune ierr = SNESSetCountersReset(snes->pc,PETSC_FALSE);CHKERRQ(ierr); 497831823bd8SMatthew G Knepley } 497931823bd8SMatthew G Knepley *pc = snes->pc; 498031823bd8SMatthew G Knepley PetscFunctionReturn(0); 498131823bd8SMatthew G Knepley } 498231823bd8SMatthew G Knepley 4983c40d0f55SPeter Brune #undef __FUNCT__ 49843ad1a0b9SPatrick Farrell #define __FUNCT__ "SNESHasNPC" 49853ad1a0b9SPatrick Farrell /*@ 49863ad1a0b9SPatrick Farrell SNESHasNPC - Returns whether a nonlinear preconditioner exists 49873ad1a0b9SPatrick Farrell 49883ad1a0b9SPatrick Farrell Not Collective 49893ad1a0b9SPatrick Farrell 49903ad1a0b9SPatrick Farrell Input Parameter: 49913ad1a0b9SPatrick Farrell . snes - iterative context obtained from SNESCreate() 49923ad1a0b9SPatrick Farrell 49933ad1a0b9SPatrick Farrell Output Parameter: 49943ad1a0b9SPatrick Farrell . has_npc - whether the SNES has an NPC or not 49953ad1a0b9SPatrick Farrell 49963ad1a0b9SPatrick Farrell Level: developer 49973ad1a0b9SPatrick Farrell 49983ad1a0b9SPatrick Farrell .keywords: SNES, has, preconditioner 49993ad1a0b9SPatrick Farrell .seealso: SNESSetNPC(), SNESGetNPC() 50003ad1a0b9SPatrick Farrell @*/ 50013ad1a0b9SPatrick Farrell PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc) 50023ad1a0b9SPatrick Farrell { 50033ad1a0b9SPatrick Farrell PetscFunctionBegin; 50043ad1a0b9SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5005*60c7cefcSBarry Smith *has_npc = (PetscBool) (snes->pc ? PETSC_TRUE : PETSC_FALSE); 50063ad1a0b9SPatrick Farrell PetscFunctionReturn(0); 50073ad1a0b9SPatrick Farrell } 50083ad1a0b9SPatrick Farrell 50093ad1a0b9SPatrick Farrell #undef __FUNCT__ 5010be95d8f1SBarry Smith #define __FUNCT__ "SNESSetNPCSide" 5011c40d0f55SPeter Brune /*@ 5012be95d8f1SBarry Smith SNESSetNPCSide - Sets the preconditioning side. 5013c40d0f55SPeter Brune 5014c40d0f55SPeter Brune Logically Collective on SNES 5015c40d0f55SPeter Brune 5016c40d0f55SPeter Brune Input Parameter: 5017c40d0f55SPeter Brune . snes - iterative context obtained from SNESCreate() 5018c40d0f55SPeter Brune 5019c40d0f55SPeter Brune Output Parameter: 5020c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5021c40d0f55SPeter Brune .vb 5022c40d0f55SPeter Brune PC_LEFT - left preconditioning (default) 5023c40d0f55SPeter Brune PC_RIGHT - right preconditioning 5024c40d0f55SPeter Brune .ve 5025c40d0f55SPeter Brune 5026c40d0f55SPeter Brune Options Database Keys: 5027c40d0f55SPeter Brune . -snes_pc_side <right,left> 5028c40d0f55SPeter Brune 5029c40d0f55SPeter Brune Level: intermediate 5030c40d0f55SPeter Brune 5031c40d0f55SPeter Brune .keywords: SNES, set, right, left, side, preconditioner, flag 5032c40d0f55SPeter Brune 5033be95d8f1SBarry Smith .seealso: SNESGetNPCSide(), KSPSetPCSide() 5034c40d0f55SPeter Brune @*/ 5035be95d8f1SBarry Smith PetscErrorCode SNESSetNPCSide(SNES snes,PCSide side) 5036c40d0f55SPeter Brune { 5037c40d0f55SPeter Brune PetscFunctionBegin; 5038c40d0f55SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5039c40d0f55SPeter Brune PetscValidLogicalCollectiveEnum(snes,side,2); 5040c40d0f55SPeter Brune snes->pcside = side; 5041c40d0f55SPeter Brune PetscFunctionReturn(0); 5042c40d0f55SPeter Brune } 5043c40d0f55SPeter Brune 5044c40d0f55SPeter Brune #undef __FUNCT__ 5045be95d8f1SBarry Smith #define __FUNCT__ "SNESGetNPCSide" 5046c40d0f55SPeter Brune /*@ 5047be95d8f1SBarry Smith SNESGetNPCSide - Gets the preconditioning side. 5048c40d0f55SPeter Brune 5049c40d0f55SPeter Brune Not Collective 5050c40d0f55SPeter Brune 5051c40d0f55SPeter Brune Input Parameter: 5052c40d0f55SPeter Brune . snes - iterative context obtained from SNESCreate() 5053c40d0f55SPeter Brune 5054c40d0f55SPeter Brune Output Parameter: 5055c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5056c40d0f55SPeter Brune .vb 5057c40d0f55SPeter Brune PC_LEFT - left preconditioning (default) 5058c40d0f55SPeter Brune PC_RIGHT - right preconditioning 5059c40d0f55SPeter Brune .ve 5060c40d0f55SPeter Brune 5061c40d0f55SPeter Brune Level: intermediate 5062c40d0f55SPeter Brune 5063c40d0f55SPeter Brune .keywords: SNES, get, right, left, side, preconditioner, flag 5064c40d0f55SPeter Brune 5065be95d8f1SBarry Smith .seealso: SNESSetNPCSide(), KSPGetPCSide() 5066c40d0f55SPeter Brune @*/ 5067be95d8f1SBarry Smith PetscErrorCode SNESGetNPCSide(SNES snes,PCSide *side) 5068c40d0f55SPeter Brune { 5069c40d0f55SPeter Brune PetscFunctionBegin; 5070c40d0f55SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5071c40d0f55SPeter Brune PetscValidPointer(side,2); 5072c40d0f55SPeter Brune *side = snes->pcside; 5073c40d0f55SPeter Brune PetscFunctionReturn(0); 5074c40d0f55SPeter Brune } 5075c40d0f55SPeter Brune 50769e764e56SPeter Brune #undef __FUNCT__ 50777601faf0SJed Brown #define __FUNCT__ "SNESSetLineSearch" 50789e764e56SPeter Brune /*@ 50797601faf0SJed Brown SNESSetLineSearch - Sets the linesearch on the SNES instance. 50809e764e56SPeter Brune 50819e764e56SPeter Brune Collective on SNES 50829e764e56SPeter Brune 50839e764e56SPeter Brune Input Parameters: 50849e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 50859e764e56SPeter Brune - linesearch - the linesearch object 50869e764e56SPeter Brune 50879e764e56SPeter Brune Notes: 50887601faf0SJed Brown Use SNESGetLineSearch() to retrieve the preconditioner context (for example, 50899e764e56SPeter Brune to configure it using the API). 50909e764e56SPeter Brune 50919e764e56SPeter Brune Level: developer 50929e764e56SPeter Brune 50939e764e56SPeter Brune .keywords: SNES, set, linesearch 50947601faf0SJed Brown .seealso: SNESGetLineSearch() 50959e764e56SPeter Brune @*/ 50967601faf0SJed Brown PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch) 50979e764e56SPeter Brune { 50989e764e56SPeter Brune PetscErrorCode ierr; 50999e764e56SPeter Brune 51009e764e56SPeter Brune PetscFunctionBegin; 51019e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5102f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 51039e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 51049e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 5105f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 5106f5af7f23SKarl Rupp 51079e764e56SPeter Brune snes->linesearch = linesearch; 5108f5af7f23SKarl Rupp 51093bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr); 51109e764e56SPeter Brune PetscFunctionReturn(0); 51119e764e56SPeter Brune } 51129e764e56SPeter Brune 51139e764e56SPeter Brune #undef __FUNCT__ 51147601faf0SJed Brown #define __FUNCT__ "SNESGetLineSearch" 5115a34ceb2aSJed Brown /*@ 51167601faf0SJed Brown SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 51178141a3b9SPeter Brune or creates a default line search instance associated with the SNES and returns it. 51189e764e56SPeter Brune 51199e764e56SPeter Brune Not Collective 51209e764e56SPeter Brune 51219e764e56SPeter Brune Input Parameter: 51229e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 51239e764e56SPeter Brune 51249e764e56SPeter Brune Output Parameter: 51259e764e56SPeter Brune . linesearch - linesearch context 51269e764e56SPeter Brune 5127162e0bf5SPeter Brune Level: beginner 51289e764e56SPeter Brune 51299e764e56SPeter Brune .keywords: SNES, get, linesearch 5130162e0bf5SPeter Brune .seealso: SNESSetLineSearch(), SNESLineSearchCreate() 51319e764e56SPeter Brune @*/ 51327601faf0SJed Brown PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch) 51339e764e56SPeter Brune { 51349e764e56SPeter Brune PetscErrorCode ierr; 51359e764e56SPeter Brune const char *optionsprefix; 51369e764e56SPeter Brune 51379e764e56SPeter Brune PetscFunctionBegin; 51389e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 51399e764e56SPeter Brune PetscValidPointer(linesearch, 2); 51409e764e56SPeter Brune if (!snes->linesearch) { 51419e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 514282f516ccSBarry Smith ierr = SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch);CHKERRQ(ierr); 5143f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 5144b1dca40bSPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 51459e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 51463bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr); 51479e764e56SPeter Brune } 51489e764e56SPeter Brune *linesearch = snes->linesearch; 51499e764e56SPeter Brune PetscFunctionReturn(0); 51509e764e56SPeter Brune } 51519e764e56SPeter Brune 515269b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 5153c6db04a5SJed Brown #include <mex.h> 515469b4f73cSBarry Smith 51558f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 51568f6e6473SBarry Smith 51570807856dSBarry Smith #undef __FUNCT__ 51580807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 51590807856dSBarry Smith /* 5160bf388a1fSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with SNESSetFunctionMatlab(). 51610807856dSBarry Smith 51620807856dSBarry Smith Collective on SNES 51630807856dSBarry Smith 51640807856dSBarry Smith Input Parameters: 51650807856dSBarry Smith + snes - the SNES context 51660807856dSBarry Smith - x - input vector 51670807856dSBarry Smith 51680807856dSBarry Smith Output Parameter: 51690807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 51700807856dSBarry Smith 51710807856dSBarry Smith Notes: 51720807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 51730807856dSBarry Smith implementations, so most users would not generally call this routine 51740807856dSBarry Smith themselves. 51750807856dSBarry Smith 51760807856dSBarry Smith Level: developer 51770807856dSBarry Smith 51780807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 51790807856dSBarry Smith 51800807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 518161b2408cSBarry Smith */ 51827087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 51830807856dSBarry Smith { 5184e650e774SBarry Smith PetscErrorCode ierr; 51858f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext*)ctx; 51868f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 51878f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 518891621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 5189e650e774SBarry Smith 51900807856dSBarry Smith PetscFunctionBegin; 51910807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 51920807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 51930807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 51940807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 51950807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 51960807856dSBarry Smith 51970807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 5198e650e774SBarry Smith 519991621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 5200e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 5201e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 520291621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 520391621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 520491621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 52058f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 52068f6e6473SBarry Smith prhs[4] = sctx->ctx; 5207b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 5208e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 5209e650e774SBarry Smith mxDestroyArray(prhs[0]); 5210e650e774SBarry Smith mxDestroyArray(prhs[1]); 5211e650e774SBarry Smith mxDestroyArray(prhs[2]); 52128f6e6473SBarry Smith mxDestroyArray(prhs[3]); 5213e650e774SBarry Smith mxDestroyArray(plhs[0]); 52140807856dSBarry Smith PetscFunctionReturn(0); 52150807856dSBarry Smith } 52160807856dSBarry Smith 52170807856dSBarry Smith #undef __FUNCT__ 52180807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 521961b2408cSBarry Smith /* 52200807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 52210807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 5222e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 52230807856dSBarry Smith 52240807856dSBarry Smith Logically Collective on SNES 52250807856dSBarry Smith 52260807856dSBarry Smith Input Parameters: 52270807856dSBarry Smith + snes - the SNES context 52280807856dSBarry Smith . r - vector to store function value 5229f8b49ee9SBarry Smith - f - function evaluation routine 52300807856dSBarry Smith 52310807856dSBarry Smith Notes: 52320807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 52330807856dSBarry Smith $ f'(x) x = -f(x), 52340807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 52350807856dSBarry Smith 52360807856dSBarry Smith Level: beginner 52370807856dSBarry Smith 5238c5b75c40SBarry Smith Developer Note: This bleeds the allocated memory SNESMatlabContext *sctx; 5239c5b75c40SBarry Smith 52400807856dSBarry Smith .keywords: SNES, nonlinear, set, function 52410807856dSBarry Smith 52420807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 524361b2408cSBarry Smith */ 5244f8b49ee9SBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *f,mxArray *ctx) 52450807856dSBarry Smith { 52460807856dSBarry Smith PetscErrorCode ierr; 52478f6e6473SBarry Smith SNESMatlabContext *sctx; 52480807856dSBarry Smith 52490807856dSBarry Smith PetscFunctionBegin; 52508f6e6473SBarry Smith /* currently sctx is memory bleed */ 5251854ce69bSBarry Smith ierr = PetscNew(&sctx);CHKERRQ(ierr); 5252f8b49ee9SBarry Smith ierr = PetscStrallocpy(f,&sctx->funcname);CHKERRQ(ierr); 52538f6e6473SBarry Smith /* 52548f6e6473SBarry Smith This should work, but it doesn't 52558f6e6473SBarry Smith sctx->ctx = ctx; 52568f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 52578f6e6473SBarry Smith */ 52588f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 52598f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 52600807856dSBarry Smith PetscFunctionReturn(0); 52610807856dSBarry Smith } 526269b4f73cSBarry Smith 526361b2408cSBarry Smith #undef __FUNCT__ 526461b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 526561b2408cSBarry Smith /* 5266bf388a1fSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with SNESSetJacobianMatlab(). 526761b2408cSBarry Smith 526861b2408cSBarry Smith Collective on SNES 526961b2408cSBarry Smith 527061b2408cSBarry Smith Input Parameters: 527161b2408cSBarry Smith + snes - the SNES context 527261b2408cSBarry Smith . x - input vector 527361b2408cSBarry Smith . A, B - the matrices 527461b2408cSBarry Smith - ctx - user context 527561b2408cSBarry Smith 527661b2408cSBarry Smith Level: developer 527761b2408cSBarry Smith 527861b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 527961b2408cSBarry Smith 528061b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 528161b2408cSBarry Smith @*/ 5282f3229a78SSatish Balay PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat A,Mat B,void *ctx) 528361b2408cSBarry Smith { 528461b2408cSBarry Smith PetscErrorCode ierr; 528561b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext*)ctx; 528661b2408cSBarry Smith int nlhs = 2,nrhs = 6; 528761b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 528861b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 528961b2408cSBarry Smith 529061b2408cSBarry Smith PetscFunctionBegin; 529161b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 529261b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 529361b2408cSBarry Smith 529461b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 529561b2408cSBarry Smith 529661b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 529761b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 529861b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 529961b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 530061b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 530161b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 530261b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 530361b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 530461b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 530561b2408cSBarry Smith prhs[5] = sctx->ctx; 5306b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 530761b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 530861b2408cSBarry Smith mxDestroyArray(prhs[0]); 530961b2408cSBarry Smith mxDestroyArray(prhs[1]); 531061b2408cSBarry Smith mxDestroyArray(prhs[2]); 531161b2408cSBarry Smith mxDestroyArray(prhs[3]); 531261b2408cSBarry Smith mxDestroyArray(prhs[4]); 531361b2408cSBarry Smith mxDestroyArray(plhs[0]); 531461b2408cSBarry Smith mxDestroyArray(plhs[1]); 531561b2408cSBarry Smith PetscFunctionReturn(0); 531661b2408cSBarry Smith } 531761b2408cSBarry Smith 531861b2408cSBarry Smith #undef __FUNCT__ 531961b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 532061b2408cSBarry Smith /* 532161b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 532261b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 5323e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 532461b2408cSBarry Smith 532561b2408cSBarry Smith Logically Collective on SNES 532661b2408cSBarry Smith 532761b2408cSBarry Smith Input Parameters: 532861b2408cSBarry Smith + snes - the SNES context 532961b2408cSBarry Smith . A,B - Jacobian matrices 5330f8b49ee9SBarry Smith . J - function evaluation routine 533161b2408cSBarry Smith - ctx - user context 533261b2408cSBarry Smith 533361b2408cSBarry Smith Level: developer 533461b2408cSBarry Smith 5335c5b75c40SBarry Smith Developer Note: This bleeds the allocated memory SNESMatlabContext *sctx; 5336c5b75c40SBarry Smith 533761b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 533861b2408cSBarry Smith 5339f8b49ee9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction(), J 534061b2408cSBarry Smith */ 5341f8b49ee9SBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *J,mxArray *ctx) 534261b2408cSBarry Smith { 534361b2408cSBarry Smith PetscErrorCode ierr; 534461b2408cSBarry Smith SNESMatlabContext *sctx; 534561b2408cSBarry Smith 534661b2408cSBarry Smith PetscFunctionBegin; 534761b2408cSBarry Smith /* currently sctx is memory bleed */ 5348854ce69bSBarry Smith ierr = PetscNew(&sctx);CHKERRQ(ierr); 5349f8b49ee9SBarry Smith ierr = PetscStrallocpy(J,&sctx->funcname);CHKERRQ(ierr); 535061b2408cSBarry Smith /* 535161b2408cSBarry Smith This should work, but it doesn't 535261b2408cSBarry Smith sctx->ctx = ctx; 535361b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 535461b2408cSBarry Smith */ 535561b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 535661b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 535761b2408cSBarry Smith PetscFunctionReturn(0); 535861b2408cSBarry Smith } 535969b4f73cSBarry Smith 5360f9eb7ae2SShri Abhyankar #undef __FUNCT__ 5361f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 5362f9eb7ae2SShri Abhyankar /* 5363f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 5364f9eb7ae2SShri Abhyankar 5365f9eb7ae2SShri Abhyankar Collective on SNES 5366f9eb7ae2SShri Abhyankar 5367f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 5368f9eb7ae2SShri Abhyankar @*/ 53697087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 5370f9eb7ae2SShri Abhyankar { 5371f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 537248f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext*)ctx; 5373f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 5374f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 5375f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 5376f9eb7ae2SShri Abhyankar Vec x = snes->vec_sol; 5377f9eb7ae2SShri Abhyankar 5378f9eb7ae2SShri Abhyankar PetscFunctionBegin; 5379f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5380f9eb7ae2SShri Abhyankar 5381f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 5382f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 5383f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 5384f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 5385f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 5386f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 5387f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 5388f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 5389f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 5390f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 5391f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 5392f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 5393f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 5394f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 5395f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 5396f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 5397f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 5398f9eb7ae2SShri Abhyankar } 5399f9eb7ae2SShri Abhyankar 5400f9eb7ae2SShri Abhyankar #undef __FUNCT__ 5401f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 5402f9eb7ae2SShri Abhyankar /* 5403e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 5404f9eb7ae2SShri Abhyankar 5405f9eb7ae2SShri Abhyankar Level: developer 5406f9eb7ae2SShri Abhyankar 5407c5b75c40SBarry Smith Developer Note: This bleeds the allocated memory SNESMatlabContext *sctx; 5408c5b75c40SBarry Smith 5409f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 5410f9eb7ae2SShri Abhyankar 5411f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 5412f9eb7ae2SShri Abhyankar */ 54136e4dcb14SBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *f,mxArray *ctx) 5414f9eb7ae2SShri Abhyankar { 5415f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 5416f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 5417f9eb7ae2SShri Abhyankar 5418f9eb7ae2SShri Abhyankar PetscFunctionBegin; 5419f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 5420854ce69bSBarry Smith ierr = PetscNew(&sctx);CHKERRQ(ierr); 54216e4dcb14SBarry Smith ierr = PetscStrallocpy(f,&sctx->funcname);CHKERRQ(ierr); 5422f9eb7ae2SShri Abhyankar /* 5423f9eb7ae2SShri Abhyankar This should work, but it doesn't 5424f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 5425f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 5426f9eb7ae2SShri Abhyankar */ 5427f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 54280298fd71SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,NULL);CHKERRQ(ierr); 5429f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 5430f9eb7ae2SShri Abhyankar } 5431f9eb7ae2SShri Abhyankar 543269b4f73cSBarry Smith #endif 5433